版权所有 © 2001-2006 奥斯卡·安德烈森
Copyright © 2001-2006 Oskar Andreasson
根据 GNU 自由文档许可证 1.1 版的条款,授予复制、分发和/或修改本文档的许可;不变部分为“引言”和所有小节,封面文本为“原作者:Oskar Andreasson”,没有封底文本。许可证的副本包含在标题为“GNU 自由文档许可证”的部分中。
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1; with the Invariant Sections being "Introduction" and all sub-sections, with the Front-Cover Texts being "Original Author: Oskar Andreasson", and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
本教程中的所有脚本均受 GNU 通用公共许可证保护。这些脚本是免费的;您可以根据自由软件基金会发布的 GNU 通用公共许可证(许可证版本 2)的条款重新分发和/或修改它们。
All scripts in this tutorial are covered by the GNU General Public License. The scripts are free source; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License.
分发这些脚本是希望它们有用,但不提供任何保证;甚至没有适销性或特定用途适用性的默示保证。有关更多详细信息,请参阅 GNU 通用公共许可证。
These scripts are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
您应该已在本教程中标题为“GNU 通用公共许可证”的部分下收到一份 GNU 通用公共许可证的副本;如果没有,请写信给 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License within this tutorial, under the section entitled "GNU General Public License"; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
我谨将这份文件献给我出色的姐姐、侄女和姐夫,他们给了我灵感和反馈。它们是快乐的源泉,是我需要时的一束光。谢谢你!
I would like to dedicate this document to my wonderful sister, niece and brother-in-law for giving me inspiration and feedback. They are a source of joy and a ray of light when I have need of it. Thank you!
还应该对尼内尔说一句特别的话,因为他总是鼓励我写作,并在我最需要的时候照顾我。谢谢你!
A special word should also be extended to Ninel for always encouraging my writing and for taking care of me when I needed it the most. Thank you!
其次,我想将这项工作献给所有辛勤工作的 Linux 开发人员和维护人员。正是像他们这样的人使这个美妙的操作系统成为可能。
Second of all, I would like to dedicate this work to all of the incredibly hard working Linux developers and maintainers. It is people like those who make this wonderful operating system possible.
iptables 教程的作者出生于...
The author of the iptables tutorial was born in...
不,开玩笑。8 岁时,我收到了我的第一台电脑作为圣诞礼物,一台带有 C-1541 磁盘驱动器的 Commodore 64、8 针打印机和一些游戏等。我花了好几天的时间才懒得理会。我父亲设法将其组装起来,两天后他终于学会了如何加载游戏并展示了如何自己做。我想,沉浸在计算机中的生活就在这一天诞生了。在这个阶段,我主要玩游戏,但也断断续续地尝试过几次 C-64 基本编程语言。几年后,我得到了一台 Amiga 500,它主要用于游戏和一些功课以及摆弄。接下来是 Amiga 1200。
No, jokes aside. At age 8 I got my first computer for christmas present, a Commodore 64 with a C-1541 diskdrive, 8 needle printer and some games etc. It took me several days to even bother. My father managed to put it together and after 2 days he finally learned himself how to load a game and showed how to do it for myself. A life immersed in computers was born this day I guess. I played mostly games at this stage, but did venture into the C-64 basic programming language a couple of times on and off. After some years, I got my hands on an Amiga 500, which was mainly used for games and some school work and fiddling around. Amiga 1200 was next.
早在 1993-94 年,我父亲就有足够的洞察力,不幸的是,Amiga 并不是未来的发展方向。PC 和 i386 计算机是。尽管我徒劳地尖叫,他还是给我买了一台 PC,486 50MHz,16 MB 内存,康柏电脑。这实际上是我见过的最糟糕的计算机设计之一,所有东西都是集成的,包括扬声器和 CRT 屏幕。我猜他们试图模仿当时的苹果设计,但惨遭失败。但应该指出的是,正是这台电脑让我真正进入了计算机领域。我开始真正编码,开始使用互联网,并在这台机器上实际安装了 Linux。
Back in 1993-94 My father was clearsighted enough to understand that Amiga was, unfortunately, not the way of the future. PC and i386 computers was. Despite my screams in vain he bought me a PC, 486 50MHz with 16 MB of ram, Compaq computer. This was actually one of the worst computer designs I have ever seen, everything was integrated, including speakers and CRT screen. I guess they where trying to mimic the Apple designs of the day, but failing miserably to do so. It should be noted though, that this was the computer that got me really into computers. I started coding for real, started using the Internet and actually installed Linux on this machine.
长期以来,我一直是一名狂热的 Linux 用户和管理员。我的 Linux 体验始于 1994 年,当时是通过借来的 CD 安装了 slackware。第一次安装主要是试用安装。我以前没有任何经验,花了我相当长的时间才让调制解调器运行等等,并且我一直运行双引导系统。第二次安装是在 1996 年左右,我周围没有媒体,所以我最终通过 28k8 调制解调器上的 FTP 下载了整个 slackware A、AP、D 和 N 磁盘集。由于我意识到我永远不会从使用图形界面中学到任何东西,所以我回到了基础知识。除了控制台之外什么都没有,除了 svgalib 之外没有 X11 或图形。最后,我相信这对我帮助很大。我相信没有什么可以教你如何使用某件事来真正强迫自己去做,就像我此时所做的那样。我别无选择,只能学习。我就这样坚持跑步了近两年。在此之后,我终于从头开始安装了XFree86。经过24小时的编译后,我意识到我完全错误地配置了编译,不得不从头开始编译。作为一个人,你总是难免会犯错误。它只是发生了,你最好习惯它。此外,这种构建过程教会您要有耐心。让事情顺其自然,不要强求。这种构建过程教会你要有耐心。让事情顺其自然,不要强求。这种构建过程教会你要有耐心。让事情顺其自然,不要强求。
I have for a long time been an avid Linux user and administrator. My Linux experience started in 1994 with a slackware installation from borrowed CD's. This first installation was mostly a trial installation. I had no previous experience and it took me quite some time to get modems running et cetera, and I kept running a dual boot system. The second installation, circa 1996, I had no media around so I winded up downloading the whole slackware A, AP, D and N disksets via FTP on a 28k8 modem. Since I realized I would never learn anything from using graphical interfaces, I went back to basics. Nothing but console, no X11 or graphics except for svgalib. In the end, I believe this has helped me a lot. I believe there is nothing to teach you how to use something as to actually forcing yourself to do it, as I did at this time. I had no choice but to learn. I continued running like this for close to 2 years. After this, I finally installed XFree86 from scratch. After an 24 hour compilation, I realized that I had totally misconfigured the compilation and had to restart the compilation from scratch. As a human, you are always bound to do errors. It simply happens and you better get used to it. Also, this kind of build process teaches you to be patient. Let things have its time and don't force it.
在 2000-2001 年期间,我是一小群人中的一员,他们经营一个新闻网站,主要关注 Amiga 相关新闻,但也有一些 Linux 和一般计算机新闻。该网站名为 BoingWorld,网址为 www.boingworld.com(不幸的是,该网站已不再可用)。Linux 2.3 内核已到达终点,而 2.4 内核则开始出现。此时,我意识到其中有一个半新的防火墙概念。当然,我以前接触过 ipfwadm 和 ipchains,并在某种程度上使用过它们,但从未真正深入研究过它们。我还意识到文档少得令人尴尬,我觉得为 boingworld 编写 iptables 教程可能是一个有趣的想法。言归正传,我写了您当前正在阅读的前 5-10 页内容。成为红极一时的热门作品,我继续向教程添加材料。在本教程/文档中不再可以找到原始页面,但这个概念仍然存在。
In 2000-2001 I was part of a small group of people who ran a newssite mainly focusing on Amiga related news, but also some Linux and general computer news. The site was called BoingWorld, located at www.boingworld.com (no long available unfortunately). The Linux 2.3 kernels where reaching their end of line and the 2.4 kernels where starting to pop up. At this point, I realized there was a half-new concept of firewalling inside of it. Sure I had run into ipfwadm and ipchains before and used it to some extent, but never truly gone heads first into it. I also realized there was embaerassingly little documentation and I felt it might be an interesting idea to write an iptables tutorial for boingworld. Said and done, I wrote the first 5-10 pages of what you are currently reading. Becoming a smashing hit, I continued to add material to the tutorial. The original pages are no longer anywhere to be found in this tutorial/documentation, but the concept lives on.
在此期间,我曾在几家不同的公司工作过,负责 Linux/网络管理,编写文档和课程材料,帮助数百(如果不是数千)人通过电子邮件发送有关 iptables 和 netfilter 的问题以及一般网络问题。我参加了两次 CERTconf,并在同一个会议上举行了 3 次演讲,还有 2003 年的 Netfilter 研讨会。维护和更新这项工作是一项忙碌的工作,有时甚至是忘恩负义的工作,但最终我对此感到非常高兴我为自己所做的事情感到非常自豪。在 2006 年底写这篇文章时,该项目已经濒临死亡好几年了,我对此感到遗憾。我希望在未来几年改变这一点,并且很多人会发现这项工作在未来有用,
I have worked several different companies during this time with Linux/network administration, writing documentation and course material, helped several hundred, if not thousand, people emailing questions regarding iptables and netfilter and general networking questions. I have attended two CERTconf's and held three presentations at the same conference, and also the Netfilter workshop 2003. It has been an hectic and sometimes very ungrateful job to maintain and update this work, but in the end I am very happy for it and this is something I am very proud of having done. At the time of writing this in end of 2006, the project has been close to dead for several years, and I regret this. I hope to change this in the coming years, and that a lot of people will find this work to be of future use, possibly adding to the family of documents with other interesting documentation that might be needed.
本文档既可以作为参考阅读,也可以从头到尾阅读。它最初是作为 iptables 和某种程度上 netfilter 的简短介绍而编写的,但多年来这个重点已经发生了变化。它旨在成为 iptables 和 netfilter 的尽可能完整的参考,并至少为您可能需要理解的领域提供基本且快速的入门或重复。需要注意的是,本文档不会也不能处理 iptables 和 netfilter 范围内或之外的特定错误,也不会真正处理如何解决此类错误。
This document could either be read as a reference or from start to end. It was originally written as a small introduction to iptables and to some extent netfilter, but this focus has changed over the years. It aims at being an as complete reference as possibly to iptables and netfilter and to at least give a basic and fast primer or repetition to the areas that you might need to understand. It should be noted that this document will not, nor will it be able to, deal with specific bugs inside or outside the scope of iptables and netfilter, nor does it really deal with how to get around bugs like this.
如果您在 iptables 或任何子组件中发现特殊的错误或行为,您应该联系 Netfilter 邮件列表并告诉他们该问题,他们可以告诉您这是否是一个真正的错误或是否已修复。iptables 和 Netfilter 中存在与安全相关的 bug,偶尔会漏掉一两个,这是不可避免的。这些内容正确地显示在Netfilter 主页的首页上,您应该在那里获取有关此类主题的信息。
If you find peculiar bugs or behaviors in iptables or any of the subcomponents, you should contact the Netfilter mailing lists and tell them about the problem and they can tell you if this is a real bug or if it has already been fixed. There are security related bugs found in iptables and Netfilter, one or two do slip by once in a while, it's inevitable. These are properly shown on the front page of the Netfilter main page, and that is where you should go to get information on such topics.
上述内容还意味着本教程中可用的规则集并不是为了处理 Netfilter 内部的实际错误而编写的。它们的主要目标是简单地展示如何以一种简单的方式设置规则来处理我们可能遇到的所有问题。例如,本教程不会介绍我们如何关闭 HTTP 端口,原因很简单,Apache 在 1.2.12 版本中恰好容易受到攻击(实际上已介绍了这一点,但不是因为这个原因)。
The above also implies that the rule-sets available with this tutorial are not written to deal with actual bugs inside Netfilter. The main goal of them is to simply show how to set up rules in a nice simple fashion that deals with all problems we may run into. For example, this tutorial will not cover how we would close down the HTTP port for the simple reason that Apache happens to be vulnerable in version 1.2.12 (This is covered really, though not for that reason).
编写本文档的目的是为每个人提供有关如何开始使用 iptables 的良好而简单的入门知识,但同时它的创建也尽可能完整。它不包含 patch-o-matic 中的任何目标或匹配项,原因很简单,即需要花费太多精力来更新此类列表。如果您需要有关 patch-o-matic 更新的信息,您应该阅读 patch-o-matic 中附带的信息以及 Netfilter 主页上提供的其他文档。
This document was written to give everyone a good and simple primer at how to get started with iptables, but at the same time it was created to be as complete as possible. It does not contain any targets or matches that are in patch-o-matic for the simple reason that it would require too much effort to keep such a list updated. If you need information about the patch-o-matic updates, you should read the info that comes with it in patch-o-matic as well as the other documentations available on the Netfilter main page.
如果您对添加有任何建议,或者您认为您发现本文档未涵盖的 iptables 和 netfilter 领域的任何问题,请随时与我联系。我将非常乐意查看它并可能添加可能缺少的内容。
If you have any suggestions on additions or if you think you find any problems around the area of iptables and netfilter not covered in this document feel free to contact me about this. I will be more than happy to take a look at it and possibly add what might be missing.
本文档需要一些有关 Linux/Unix、shell 脚本以及如何编译自己的内核的先前知识,以及一些有关内核内部结构的简单知识。
This document requires some previous knowledge about Linux/Unix, shell scripting, as well as how to compile your own kernel, and some simple knowledge about the kernel internals.
我已尽可能地消除在完全掌握本文档之前所需的所有先决条件,但在某种程度上,不需要一些先前的知识是根本不可能的。
I have tried as much as possible to eradicate all prerequisites needed before fully grasping this document, but to some extent it is simply impossible to not need some previous knowledge.
当涉及命令、文件和其他特定信息时,本文档使用以下约定。
The following conventions are used in this document when it comes to commands, files and other specific information.
长代码摘录和命令输出的打印方式如下所示。这包括屏幕转储和从控制台获取的更大示例。
[blueflux@work1 嘶嘶声]$ ls
默认eth0 lo
[blueflux@work1 嘶鸣]$
Long code excerpts and command-outputs are printed like shown below. This includes screendumps and larger examples taken from the console.
[blueflux@work1 neigh]$ ls
default eth0 lo
[blueflux@work1 neigh]$
本教程中的所有命令和程序名称均以粗体显示。这包括您可能键入的所有命令或您键入的命令的一部分。
All commands and program names in the tutorial are shown in bold typeface. This includes all the commands that you might type, or part of the command that you type.
所有系统项(例如硬件)以及内核内部或抽象系统项(例如环回接口)均以斜体显示。
All system items such as hardware, and also kernel internals or abstract system items such as the loopback interface are all shown in an italic typeface.
计算机输出在文本中以这种方式格式化。计算机输出可以概括为计算机在控制台上提供的所有输出。
computer output is formatted in this way in the text. Computer output could be summed up as all the output that the computer will give you on the console.
文件系统中的文件名和路径显示为 /usr/local/bin/iptables。
filenames and paths in the file-system are shown like /usr/local/bin/iptables.
好吧,我发现 HOWTO 中有一大片空白,缺少有关新 Linux 2.4.x 内核中的 iptables 和 Netfilter 功能的信息。除此之外,我将尝试回答一些人可能对状态匹配等新可能性提出的问题。其中大部分内容将通过示例rc.firewall.txt文件进行说明,您可以在/etc/rc.d/脚本中使用该文件。是的,这个文件最初是基于伪装的 HOWTO,供那些认识它的人使用。
Well, I found a big empty space in the HOWTO's out there lacking in information about the iptables and Netfilter functions in the new Linux 2.4.x kernels. Among other things, I'm going to try to answer questions that some might have about the new possibilities like state matching. Most of this will be illustrated with an example rc.firewall.txt file that you can use in your /etc/rc.d/ scripts. Yes, this file was originally based upon the masquerading HOWTO for those of you who recognize it.
另外,我编写了一个小脚本,以防万一您在配置过程中像我一样搞砸了,如rc.flush-iptables.txt。
Also, there's a small script that I wrote just in case you screw up as much as I did during the configuration available as rc.flush-iptables.txt.
我最初为 boingworld.com 编写了一个非常小的教程,该网站是一个 Amiga/Linux/General 新闻网站,几年前由一小群人(包括我)运营。由于有大量的读者和评论,我继续写下去。最初的印刷版大约有 10-15 页 A4 页,此后一直在缓慢而稳定地增长。很多人帮助了我,进行拼写检查、错误更正等。在撰写本文时,仅 https://www.frozentux.net/iptables-tutorial/ 网站就有超过 600.000 次独特点击。
I originally wrote this as a very small tutorial for boingworld.com, which was an Amiga/Linux/General newssite that a small group of people, including me, ran a couple of years back. Due to the fantastic amount of readers and comments that I got from it, I continued to write on it. The original version was approximately 10-15 A4 pages in printed version and has since been growing slowly but steadily. A huge amount of people has helped me out, spellchecking, bug corrections, etc. At the time of writing this, the https://www.frozentux.net/iptables-tutorial/ site has had over 600.000 unique hits alone.
本文档旨在指导您逐步完成设置过程,并希望能帮助您了解有关 iptables 包的更多信息。我这里的大部分内容都基于示例 rc.firewall 文件,因为我发现该示例是学习如何使用 iptables 的好方法。我决定只遵循基本的链结构,并从那里遍历遍历的每一条链并解释脚本的工作原理。这样,教程就有点难以理解,尽管这种方式更符合逻辑。每当您发现难以理解的内容时,请返回本教程。
This document was written to guide you through the setup process step by step and hopefully help you to understand some more about the iptables package. I have based most of the stuff here on the example rc.firewall file, since I found that example to be a good way to learn how to use iptables. I decided to just follow the basic chain structure and from there walk through each and one of the chains traversed and explain how the script works. That way the tutorial is a little bit harder to follow, though this way is more logical. Whenever you find something that's hard to understand, just come back to this tutorial.
本文档包含一些术语,在阅读它们之前可能需要更详细的解释。本节将尝试涵盖最明显的内容以及我如何选择在本文档中使用它们。
This document contains a few terms that may need more detailed explanations before you read them. This section will try to cover the most obvious ones and how I have chosen to use them within this document.
连接 - 在本文档中通常将其称为一系列彼此相关的数据包。这些数据包将彼此称为已建立的连接类型。换句话说,连接是一系列交换的数据包。在TCP中,这主要是指通过3次握手建立连接,然后直到释放握手才认为这是一个连接。
Connection - This is generally referred to in this document as a series of packets relating to each other. These packets refer to each other as an established kind of connection. A connection is in another word a series of exchanged packets. In TCP, this mainly means establishing a connection via the 3-way handshake, and then this is considered a connection until the release handshake.
DNAT - 目标网络地址转换。DNAT 是指转换数据包的目标 IP 地址的技术,或者简单地说是更改它的技术。它与 SNAT 一起使用,允许多个主机共享单个 Internet 可路由 IP 地址,并仍然提供服务器服务。这通常是通过为不同的端口分配互联网可路由的 IP 地址来完成的,然后告诉 Linux 路由器将流量发送到哪里。
DNAT - Destination Network Address Translation. DNAT refers to the technique of translating the Destination IP address of a packet, or to change it simply put. This is used together with SNAT to allow several hosts to share a single Internet routable IP address, and to still provide Server Services. This is normally done by assigning different ports with an Internet routable IP address, and then tell the Linux router where to send the traffic.
IPSEC - 互联网协议安全是一种用于加密 IPv4 数据包并通过互联网安全发送它们的协议。有关 IPSEC 的更多信息,请查看其他资源和链接附录,了解有关该主题的其他资源。
IPSEC - Internet Protocol Security is a protocol used to encrypt IPv4 packets and sending them securely over the Internet. For more information on IPSEC, look in the Other resources and links appendix for other resources on the topic.
内核空间——这或多或少与用户空间相反。这意味着操作发生在内核内部,而不是内核外部。
Kernel space - This is more or less the opposite of User space. This implies the actions that take place within the kernel, and not outside of the kernel.
数据包 - 通过网络发送的单个单元,包含标头和数据部分。例如,IP数据包或TCP数据包。在征求意见 (RFC) 中,数据包没有那么概括,IP 数据包称为数据报,而 TCP 数据包称为段。为了简单起见,我选择将本文档中的几乎所有内容称为数据包。
Packet - A singular unit sent over a network, containing a header and a data portion. For example, an IP packet or an TCP packet. In Request For Comments (RFC's) a packet isn't so generalized, instead IP packets are called datagrams, while TCP packets are called segments. I have chosen to call pretty much everything packets in this document for simplicity.
QoS - 服务质量是一种指定数据包应如何处理以及发送数据包时应接收哪种服务质量的方法。有关此主题的更多信息,请查看TCP/IP 复习章节以及有关该主题的外部资源的 其他资源和链接附录。
QoS - Quality of Service is a way of specifying how a packet should be handled and what kind of service quality it should receive while sending it. For more information on this topic, take a look in the TCP/IP repetition chapter as well as the Other resources and links appendix for external resources on the subject.
段 - TCP 段与数据包几乎相同,但它是 TCP 数据包的正式术语。
Segment - A TCP segment is pretty much the same as an packet, but a formalized word for a TCP packet.
流 - 该术语指的是发送和接收以某种方式相互关联的数据包的连接。基本上,我将这个术语用于任何类型的双向发送两个或多个数据包的连接。在 TCP 中,这可能意味着发送 SYN 然后回复 SYN/ACK 的连接,但也可能意味着发送 SYN 然后回复 ICMP 主机不可达的连接。换句话说,我对这个术语的使用非常宽松。
Stream - This term refers to a connection that sends and receives packets that are related to each other in some fashion. Basically, I have used this term for any kind of connection that sends two or more packets in both directions. In TCP this may mean a connection that sends a SYN and then replies with an SYN/ACK, but it may also mean a connection that sends a SYN and then replies with an ICMP Host unreachable. In other words, I use this term very loosely.
SNAT - 源网络地址转换。这是指用于将数据包中的一个源地址转换为另一个源地址的技术。由于目前 IPv4 中可用的 IP 地址短缺(IPv6 将解决这个问题),这使得多个主机可以共享单个 Internet 可路由 IP 地址。
SNAT - Source Network Address Translation. This refers to the techniques used to translate one source address to another in a packet. This is used to make it possible for several hosts to share a single Internet routable IP address, since there is currently a shortage of available IP addresses in IPv4 (IPv6 will solve this).
状态 - 该术语是指数据包所处的状态,根据RFC 793 - 传输控制协议或根据 Netfilter/iptables 中使用的用户端状态。请注意,内部和外部使用的状态并不完全遵循 RFC 793 规范。主要原因是 Netfilter 必须对连接和数据包做出一些假设。
State - This term refers to which state the packet is in, either according to RFC 793 - Transmission Control Protocol or according to userside states used in Netfilter/iptables. Note that the used states internally, and externally, do not follow the RFC 793 specification fully. The main reason is that Netfilter has to make several assumptions about the connections and packets.
用户空间——这个术语指的是内核之外发生的一切。例如,调用 iptables -h 发生在内核外部,而 iptables -A FORWARD -p tcp -j ACCEPT (部分)发生在内核内部,因为新规则已添加到规则集中。
User space - With this term I mean everything and anything that takes place outside the kernel. For example, invoking iptables -h takes place outside the kernel, while iptables -A FORWARD -p tcp -j ACCEPT takes place (partially) within the kernel, since a new rule is added to the ruleset.
用户空间 - 请参阅用户空间。
Userland - See User space.
VPN - 虚拟专用网络是一种用于在非专用网络(例如互联网)上创建虚拟专用网络的技术。IPSEC 是一种用于创建 VPN 连接的技术。OpenVPN 是另一个。
VPN - Virtual Private Network is a technique used to create virtually private networks over non-private networks, such as the Internet. IPSEC is one technique used to create VPN connections. OpenVPN is another.
本章对为什么编写此文档以及如何编写此文档进行了一些深入的了解。它还解释了整个文档中使用的一些常用术语。
This chapter has given some small insight into why this document was written and how it was written. It also explained some common terms used throughout the document.
下一章将对 TCP/IP 进行相当长的介绍和重复。基本上,这意味着 IP 协议及其一些常与 iptables 和 netfilter 一起使用的子协议。它们是 TCP、UDP、ICMP 和 SCTP。与其他协议相比,SCTP 是一个相当新的标准,因此我们花费了大量的空间和时间来为所有仍然不太熟悉该协议的人描述该协议。下一章还将讨论目前使用的一些基本和更高级的路由技术。
The next chapter will bring up a rather lengthy introduction and repetition to TCP/IP. Basically this means the IP protocol and some of its sub-protocols that are commonly used with iptables and netfilter. These are TCP, UDP, ICMP and SCTP. SCTP is a rather new standard in comparison to the other protocols, hence quite a lot of space and time has gone into describing this protocol for all of those who are still not quite familiar with it. The next chapter will also discuss some basic and more advanced routing techniques used today.
iptables 是一个知识极其密集的工具。这意味着 iptables 需要相当多的知识才能充分利用 iptables。除此之外,您必须对 TCP/IP 协议有很好的了解。
Iptables is an extremely knowledge intensive tool. This means that iptables takes quite a bit of knowledge to be able to use iptables to it's full extent. Among other things, you must have a very good understanding of the TCP/IP protocol.
本章旨在解释在继续使用 iptables 之前“必须理解”的 TCP/IP 内容。我们将了解 IP、TCP、UDP 和 ICMP 协议及其标头,以及每个协议的一般用法以及它们如何相互关联。Iptables 在互联网层和传输层中工作,因此,本章也将主要关注这些层。
This chapter aims at explaining the pure "must understands" of TCP/IP before you can go on and work with iptables. Among the things we will go through are the IP, TCP, UDP and ICMP protocols and their headers, and general usages of each of these protocols and how they correlate to each other. Iptables works inside Internet and Transport layers, and because of that, this chapter will focus mainly on those layers as well.
Iptables 还能够在更高层上工作,例如应用程序层。但是,它不是为此任务而构建的,也不应该用于这种用途。我将在IP 过滤介绍章节中对此进行更多解释。
Iptables is also able to work on higher layers, such as the Application layer. However, it was not built for this task, and should not be used for that kind of usage. I will explain more about this in the IP filtering introduction chapter.
如前所述,TCP/IP 是多层的。这意味着我们有一个功能在一个深度运行,另一个功能在另一个级别运行,等等。我们拥有所有这些层的原因实际上非常简单。
TCP/IP is, as already stated, multi-layered. This means that we have one functionality running at one depth, and another one at another level, etcetera. The reason that we have all of these layers is actually very simple.
最大的原因是整个架构的可扩展性非常好。例如,我们可以向应用程序层添加新功能,而无需重新实现整个 TCP/IP 堆栈代码,或将完整的 TCP/IP 堆栈包含到实际应用程序中。就像我们每次制作新的网络接口卡时不需要重写每个程序一样。每一层都需要尽可能少地了解彼此,以保持它们的分离。
The biggest reason is that the whole architecture is very extensible. We can add new functionality to the application layers, for example, without having to reimplement the whole TCP/IP stack code, or to include a complete TCP/IP stack into the actual application. Just the same way as we don't need to rewrite every single program, every time that we make a new network interface card. Each layer should need to know as little as possible about each other, to keep them separated.
当我们谈论驻留在内核内部的 TCP/IP 编程代码时,我们通常谈论的是 TCP/IP 堆栈。TCP/IP 堆栈仅意味着使用的所有子层,从网络访问层一直到应用层。 When we are talking about the programming code of TCP/IP which resides inside the kernel, we are often talking about the TCP/IP stack. The TCP/IP stack simply means all of the sublayers used, from the Network access layer and all the way up to the Application layer. |
在讨论层时,需要遵循两种基本架构。其中之一是 OSI(开放系统互连)参考模型,由 7 层组成。由于我们对 TCP/IP 层更感兴趣,因此我们在这里仅进行粗浅的了解。然而,从历史的角度来看,了解这一点很有趣,特别是如果您正在使用许多不同类型的网络。OSI 参考模型列表中的各层如下。
There are two basic architectures to follow when talking about layers. One of them is the OSI (Open Systems Interconnect) Reference Model and consists of 7 layers. We will only look at it superficially here since we are more interested in the TCP/IP layers. However, from an historical point, this is interesting to know about, especially if you are working with lots of different types of networks. The layers are as follows in the OSI Reference Model list.
关于这些参考模型中哪一个最常用存在一些讨论,但 OSI 参考模型似乎仍然是流行的参考模型。这也可能取决于您居住的地方,但是,在大多数美国和欧盟国家/地区,您在与技术人员和销售人员交谈时似乎可以默认使用 OSI 参考模型。 There is some discussion as to which of these reference models is mostly used, but it seems that the OSI reference model still is the prevalent reference model. This might also depend on where you live, however, in most US and EU countries it seems as you can default to OSI reference model while speaking to technicians and salespeople. 然而,在本文档的其余部分中,除非另有说明,我们将主要参考 TCP/IP 参考模型。 However, throughout the rest of this document, we will mainly refer to the TCP/IP reference model, unless otherwise noted. |
应用层
Application layer
表示层
Presentation layer
会话层
Session layer
传输层
Transport layer
网络层
Network layer
数据链路层
Data Link layer
物理层
Physical layer
我们发送的数据包从该列表的顶部到底部,每一层都在我们所说的封装阶段向数据包添加自己的一组标头。当数据包最终到达目的地时,数据包将向后遍历列表,并且标头被一个接一个地从数据包中剥离,每个标头为目标主机提供数据包数据最终到达应用程序或程序所需的所有信息这是注定的。
A packet that is sent by us, goes from the top and to the bottom of this list, each layer adding its own set of headers to the packet in what we call the encapsulation phase. When the packet finally reaches it's destination the packet goes backwards through the list and the headers are stripped out of the packet, one by one, each header giving the destination host all of the needed information for the packet data to finally reach the application or program that it was destined for.
我们更感兴趣的第二个也是更有趣的分层标准是 TCP/IP 协议体系结构,如TCP/IP 体系结构列表所示。对于 TCP/IP 体系结构有多少层,人们并没有达成普遍共识。然而,通常认为有3到5层可用,并且在大多数图片和解释中,将讨论4层。为了简单起见,我们将只考虑通常讨论的那四个层。
The second and more interesting layering standard that we are more interested in is the TCP/IP protocol architecture, as shown in the TCP/IP architecture list. There is no universal agreement among people on just how many layers there are in the TCP/IP architecture. However, it is generally considered that there are 3 through 5 layers available, and in most pictures and explanations, there will be 4 layers discussed. We will, for simplicities sake, only consider those four layers that are generally discussed.
应用层
Application layer
传输层
Transport layer
互联网层
Internet layer
网络接入层
Network Access layer
正如您所看到的,TCP/IP 协议集的体系结构非常类似于 OSI 参考模型,但又并非如此。与 OSI 参考模型一样,我们为进入或离开的每一层添加和减去标头。
As you can see, the architecture of the TCP/IP protocol set is very much like the OSI Reference Model, but yet not. Just the same as with the OSI Reference Model, we add and subtract headers for each layer that we enter or leave.
例如,让我们使用现代计算机网络最常见的类比之一——蜗牛邮件。一切都是按步骤完成的,就像 TCP/IP 中的一切一样。
For example, lets use one of the most common analogies to modern computer networking, the snail-mail letter. Everything is done in steps, just as is everything in TCP/IP.
您想给某人写一封信,询问他们的近况以及他们在做什么。为此,您必须首先创建数据或问题。实际数据将位于应用程序层内部。
You want to send a letter to someone asking how they are, and what they are doing. To do this, you must first create the data, or questions. The actual data would be located inside the Application layer.
之后,我们将写在一张纸上的数据放入信封内,并在上面写上这封信的收件人是特定公司或家庭中的谁。也许像下面的例子:
After this we would put the data written on a sheet of paper inside an envelope and write on it to whom the letter is destined for within a specific company or household. Perhaps something like the example below:
收件人:约翰·多伊这相当于 TCP/IP 中的传输层。在传输层中,如果我们处理 TCP,则这相当于某个端口(例如端口 25)。
This is equivalent to the the Transport layer, as it is known in TCP/IP. In the Transport layer, if we were dealing with TCP, this would have been equivalent to some port (e.g., port 25).
此时我们将收件人的地址写在信封上,比如这样:
At this point we write the address on the envelope of the recipient, such as this:
V. Andersgardsgatan 2 41715 哥德堡类比起来,这与互联网层相同。互联网层包含告诉我们在 TCP/IP 网络中到达接收者或主机的位置的信息。就像信封上的收件人一样。换句话说,这相当于 IP 地址(例如,IP 192.168.0.4)。
This would in the analogy be the same as the Internet layer. The internet layer contains information telling us where to reach the recipient, or host, in a TCP/IP network. Just the same way as the recipient on an envelope. This would be the equivalent of the IP address in other words (e.g., IP 192.168.0.4).
最后一步是将整封信放入邮箱。这样做大约相当于将数据包放入网络访问层。网络访问层包含用于访问数据包传输的实际物理网络的功能和例程。
The final step is to put the whole letter in a postbox. Doing this would approximately equal to putting a packet into the Network Access Layer. The network access layer contains the functions and routines for accessing the actual physical network that the packet should be transported over.
当收件人最终收到信件时,他会从信封和地址等中打开整封信(拆封)。他收到的信可能需要回复,也可能不需要。在任何一种情况下,接收者都可以通过颠倒他收到的原始信件上的接收者和发送者地址来回复该信件,以便接收者成为发送者,发送者成为接收者。
When the receiver finally receives the letter, he will open the whole letter from the envelope and address etc (decapsulate it). The letter he receives may either require a reply or not. In either case, the letter may be replied upon by the receiver, by reversing the receiver and transmitter addresses on the original letter he received, so that receiver becomes transmitter, and transmitter becomes receiver.
理解 iptables 过去和现在都是专门为在互联网和传输层的标头上工作而构建的这一点非常重要。也可以在应用程序和网络访问层中使用 iptables 进行一些非常基本的过滤,但它不是为此设计的,也不是非常适合这些目的。 It is very important to understand that iptables was and is specifically built to work on the headers of the Internet and the Transport layers. It is possible to do some very basic filtering with iptables in the Application and Network access layers as well, but it was not designed for this, nor is it very suitable for those purposes. 例如,如果我们使用字符串匹配并匹配数据包内的特定字符串,例如 get /index.html。那行得通吗?通常情况下,是的。但是,如果数据包大小非常小,则不会。原因是 iptables 是基于每个数据包工作 的,这意味着如果字符串被分成几个单独的数据包,iptables 将看不到整个字符串。因此,在应用程序层中使用某种代理进行过滤会更好。我们将在稍后的IP 过滤介绍中更详细地讨论这些问题。 For example, if we use a string match and match for a specific string inside the packet, lets say get /index.html. Will that work? Normally, yes. However, if the packet size is very small, it will not. The reason is that iptables is built to work on a per packet basis, which means that if the string is split into several separate packets, iptables will not see that whole string. For this reason, you are much, much better off using a proxy of some sort for filtering in the application layer. We will discuss these problems in more detail later on in the IP filtering introduction. |
由于 iptables 和 netfilter 主要在互联网层和传输层中运行,因此我们将在本章接下来的部分中重点关注这些层。在互联网层下,我们几乎只会看到IP协议。对此还有一些补充,例如 GRE 协议,但它们在互联网上非常罕见。此外,iptables(顾名思义)也没有很好地关注这些协议。由于所有这些因素,我们将主要关注互联网层的 IP 协议以及传输层的 TCP、UDP 和 ICMP。
As iptables and netfilter mainly operate in the Internet and Transport layers, that is the layers that we will put our main focus in, in the upcoming sections of this chapter. Under the Internet layer, we will almost exclusively see the IP protocol. There are a few additions to this, such as, for example, the GRE protocol, but they are very rare on the internet. Also, iptables is (as the name implies) not focused around these protocols very well either. Because of all these factors we will mainly focus around the IP protocol of the Internet layer, and TCP, UDP and ICMP of the Transport layer.
ICMP 协议实际上是两层之间的混合。它运行在互联网层,但它具有与 IP 协议完全相同的标头,但也有一些额外的标头,然后直接在该封装内存放数据。我们将在ICMP 特性中进一步详细讨论这一点。 The ICMP protocol is actually sort of a mix between the two layers. It runs in the Internet layer, but it has the exact same headers as the IP protocol, but also a few extra headers, and then directly inside that encapsulation, the data. We will discuss this in more detail further on, in the ICMP characteristics. |
正如我们已经说过的,IP 协议驻留在互联网层。IP 协议是 TCP/IP 堆栈中的协议,负责让您的机器、路由器、交换机等了解特定数据包的去向。该协议是整个 TCP/IP 堆栈的核心,并且构成了 Internet 中一切事物的基础。
The IP protocol resides in the Internet layer, as we have already said. The IP protocol is the protocol in the TCP/IP stack that is responsible for letting your machine, routers, switches and etcetera, know where a specific packet is going. This protocol is the very heart of the whole TCP/IP stack, and makes up the very foundation of everything in the Internet.
IP 协议封装传输层数据包,其中包含有关其来自哪个传输层协议、要去哪台主机、来自何处以及一些其他有用信息的信息。当然,所有这一切都是极其精确的标准化,具体到每一个比特。这同样适用于我们将在本章中讨论的每个协议。
The IP protocol encapsulates the Transport layer packet with information about which Transport layer protocol it came from, what host it is going to, and where it came from, and a little bit of other useful information. All of this is, of course, extremely precisely standardized, down to every single bit. The same applies to every single protocol that we will discuss in this chapter.
IP 协议有一些它必须能够处理的基本功能。它必须能够定义数据报,这是传输层创建的下一个构建块(换句话说,例如可以是 TCP、UDP 或 ICMP)。IP 协议还定义了我们今天使用的互联网寻址系统。这意味着 IP 协议定义了主机之间如何到达,当然,这也影响了我们如何路由数据包。我们所说的地址就是我们通常所说的IP地址。通常,当我们谈论 IP 地址时,我们谈论的是点分四组数字(例如127.0.0.1)。这主要是为了使 IP 地址更易于人眼读取,因为 IP 地址实际上只是一个由 1 和 0 组成的 32 位字段(127.0.0.1因此在实际的 IP 标头中将被读取为 01111111000000000000000000000001)。
The IP protocol has a couple of basic functionalities that it must be able to handle. It must be able to define the datagram, which is the next building block created by the transport layer (this may in other words be TCP, UDP or ICMP for example). The IP protocol also defines the Internet addressing system that we use today. This means that the IP protocol is what defines how to reach between hosts, and this also affects how we are able to route packets, of course. The addresses we are talking about are what we generally call an IP address. Usually when we talk about IP addresses, we talk about dotted quad numbers (e.g., 127.0.0.1). This is mostly to make the IP addresses more readable for the human eye, since the IP address is actually just a 32 bit field of 1's and 0's (127.0.0.1 would hence be read as 01111111000000000000000000000001 within the actual IP header).
IP 协议还有更多的魔力,它必须发挥它的作用。它还必须能够解封装和封装 IP 数据报(IP 数据),并从网络访问层或传输层发送或接收数据报。这似乎是显而易见的,但有时并非如此。最重要的是,它还必须执行两项重要功能,这将是防火墙和路由社区非常感兴趣的。IP 协议负责将数据包从一台主机路由到另一台主机,以及我们可能从一台主机接收到的发往另一台主机的数据包。大多数情况下,在单个网络访问主机上,这是一个非常简单的过程。您有两种不同的选择,要么数据包发往我们本地连接的网络,要么可能通过默认网关。但是,一旦开始使用防火墙或安全策略以及多个网络接口和不同的路由,这可能会给许多网络管理员带来相当大的麻烦。IP 协议的最后一个职责是,它必须对先前已分段的任何数据报进行分段并重新组装,或者需要分段以适应我们所连接的特定网络硬件拓扑的数据包大小。如果这些数据包碎片足够小,它们也可能给防火墙管理员带来非常烦人的头痛。问题是,一旦它们被分割成足够小的块,我们甚至在读取数据包的标头时都会遇到问题,更不用说实际的数据了。这可能会让很多网络管理员感到相当头疼。IP 协议的最后一个职责是,它必须对先前已分段的任何数据报进行分段并重新组装,或者需要分段以适应我们所连接的特定网络硬件拓扑的数据包大小。如果这些数据包碎片足够小,它们也可能给防火墙管理员带来非常烦人的头痛。问题是,一旦它们被分割成足够小的块,我们甚至在读取数据包的标头时都会遇到问题,更不用说实际的数据了。这可能会让很多网络管理员感到相当头疼。IP 协议的最后一个职责是,它必须对先前已分段的任何数据报进行分段并重新组装,或者需要分段以适应我们所连接的特定网络硬件拓扑的数据包大小。如果这些数据包碎片足够小,它们也可能给防火墙管理员带来非常烦人的头痛。问题是,一旦它们被分割成足够小的块,我们甚至在读取数据包的标头时都会遇到问题,更不用说实际的数据了。或者需要进行分段以适应我们所连接的特定网络硬件拓扑的数据包大小。如果这些数据包碎片足够小,它们也可能给防火墙管理员带来非常烦人的头痛。问题是,一旦它们被分割成足够小的块,我们甚至在读取数据包的标头时都会遇到问题,更不用说实际的数据了。或者需要进行分段以适应我们所连接的特定网络硬件拓扑的数据包大小。如果这些数据包碎片足够小,它们也可能给防火墙管理员带来非常烦人的头痛。问题是,一旦它们被分割成足够小的块,我们甚至在读取数据包的标头时都会遇到问题,更不用说实际的数据了。
The IP protocol has even more magic it must perform up it's sleeve. It must also be able to decapsulate and encapsulate the IP datagram (IP data) and send or receive the datagram from either the Network access layer, or the transport layer. This may seem obvious, but sometimes it is not. On top of all this, it has two big functions it must perform as well, that will be of quite interest for the firewalling and routing community. The IP protocol is responsible for routing packets from one host to another, as well as packets that we may receive from one host destined for another. Most of the time on single network access host, this is a very simple process. You have two different options, either the packet is destined for our locally attached network, or possibly through a default gateway. but once you start working with firewalls or security policies together with multiple network interfaces and different routes, it may cause quite some headache for many network administrators. The last of the responsibilities for the IP protocol is that it must fragment and reassemble any datagram that has previously been fragmented, or that needs to be fragmented to fit in to the packetsize of this specific network hardware topology that we are connected to. If these packet fragments are sufficiently small, they may cause a horribly annoying headache for firewall administrators as well. The problem is, that once they are fragmented to small enough chunks, we will start having problems to read even the headers of the packet, not to mention the actual data.
从 Linux 内核 2.4 系列和 iptables 开始,这对于大多数 Linux 防火墙来说应该不再是问题。iptables 用于状态匹配和 NAT 等的连接跟踪系统必须能够读取经过碎片整理的数据包。因此,conntrack 在所有数据包到达内核中的 netfilter/iptables 结构之前自动对所有数据包进行碎片整理。 As of Linux kernel 2.4 series, and iptables, this should no longer be a problem for most linux firewalls. The connection tracking system used by iptables for state matching and NAT'ing etc must be able to read the packet defragmented. Because of this, conntrack automatically defragments all packets before they reach the netfilter/iptables structure in the kernel. |
IP协议也是无连接协议,这又意味着IP不“协商”连接。另一方面,面向连接的协议协商连接(称为握手)),然后当所有数据发送完毕后,将其撕毁。TCP 是此类协议的一个示例,但它是在 IP 协议之上实现的。还没有面向连接的原因有几个,但其中之一是,此时还不需要握手,因为还有其他协议,这会增加不必要的高开销,并且是以这种方式弥补的如果我们没有得到答复,我们就知道数据包在传输过程中的某个地方丢失了,并重新发送原始请求。正如您所看到的,在这种情况下,发送请求然后等待指定的时间进行回复,比先发送一个数据包表示我们要打开连接,然后接收一个数据包让我们知道要好得多被打开,然后 实际发送请求,然后发送另一个数据包以断开连接并等待另一个答复。
The IP protocol is also a connectionless protocol, which in turn means that IP does not "negotiate" a connection. a connection-oriented protocol on the other hand negotiates a connection (called a handshake) and then when all data has been sent, tears it down. TCP is an example of this kind of protocol, however, it is implemented on top of the IP protocol. The reason for not being connection-oriented just yet are several, but among others, a handshake is not required at this time yet since there are other protocols that this would add an unnecessarily high overhead to, and that is made up in such a way that if we don't get a reply, we know the packet was lost somewhere in transit anyways, and resend the original request. As you can see, sending the request and then waiting for a specified amount of time for the reply in this case, is much preferred over first sending one packet to say that we want to open a connection, then receive a packet letting us know it was opened, and finally acknowledge that we know that the whole connection is actually open, and then actually send the request, and after that send another packet to tear the connection down and wait for another reply.
IP也被称为 不可靠协议,或者简单地说它不知道是否收到数据包。它只是从传输层接收数据包并执行其操作,然后将其传递到网络访问层,然后仅此而已。它可能会收到一个返回数据包,该数据包从网络访问层遍历到 IP 协议,IP 协议再次执行该操作,然后将其向上传递到传输层。但是,它并不关心是否收到回复数据包,或者另一端是否收到该数据包。同样的情况也适用于 IP 的不可靠性和无连接性,因为不可靠性需要向发送的每个数据包添加额外的回复数据包。例如,让我们考虑 DNS 查找。事实上,我们发送了一个针对 servername.com 的 DNS 请求。如果我们从未收到回复,我们就知道出了问题并重新请求查找,但在正常使用期间,我们会发出一个请求,并得到一个回复。增加该协议的可靠性意味着请求将需要两个数据包(一个请求,一个确认已收到数据包),然后需要两个数据包用于回复(一个回复,一个用于确认已收到回复的回复)。换句话说,我们只是将需要发送的数据包数量增加了一倍,并且将需要传输的数据量几乎增加了一倍。
IP is also known as an unreliable protocol, or simply put it does not know if a packet was received or not. It simply receives a packet from the transport layer and does its thing, and then passes it on to the network access layer, and then nothing more to it. It may receive a return packet, which traverses from network access layer to the IP protocol which does it's thing again, and then passes it on upwards to the Transport layer. However, it doesn't care if it gets a reply packet, or if the packet was received at the other end. Same thing applies for the unreliability of IP as for the connectionless-ness, since unreliability would require adding an extra reply packet to each packet that is sent. For example, let us consider a DNS lookup. As it is, we send a DNS request for servername.com. If we never receive a reply, we know something went wrong and re-request the lookup, but during normal use we would send out one request, and get one reply back. Adding reliability to this protocol would mean that the request would require two packets (one request, and one confirmation that the packet was received) and then two packets for the reply (one reply, and one reply to acknowledge the reply was received). In other words, we just doubled the amount of packets needed to send, and almost doubled the amount of data needed to be transmitted.
正如您从前面的 IP 协议介绍中所了解的那样,IP 数据包的标头中包含几个不同的部分。整个标头被精心划分为不同的部分,标头的每个部分都被分配尽可能小的一块来完成它的工作,只是为了给协议尽可能少的开销。您将在IP 标头图像中看到 IP 标头的确切配置。
The IP packet contains several different parts in the header as you have understood from the previous introduction to the IP protocol. The whole header is meticuluously divided into different parts, and each part of the header is allocated as small of a piece as possible to do it's work, just to give the protocol as little overhead as possible. You will see the exact configuration of the IP headers in the IP headers image.
请注意,不同标头的解释非常简短,我们只会讨论它们的绝对基础知识。对于我们讨论的每种类型的标头,我们还将列出正确的 RFC,您应该阅读这些 RFC,以进一步了解相关协议并进行技术解释。作为本说明的旁注,RFC 代表请求评论,但如今,它们对互联网社区具有完全不同的含义。与研究人员开始互相编写 RFC 时相比,它们定义并标准化了整个互联网。当时,它们只是征求意见和询问其他研究人员意见的一种方式。 Understand that the explanations of the different headers are very brief and that we will only discuss the absolute basics of them. For each type of header that we discuss, we will also list the proper RFC's that you should read for further understanding and technical explanations of the protocol in question. As a sidenote to this note, RFC stands for Request For Comments, but these days, they have a totally different meaning to the Internet community. They are what defines and standardises the whole Internet, compared to what they were when the researchers started writing RFC's to each other. Back then, they were simply requests for comments and a way of asking other researchers about their opinions. |
IP协议主要在RFC 791-Internet Protocol中描述。然而,此 RFC 也由RFC 1349 - Internet 协议套件中的服务类型更新,该 RFC 已被RFC 2474 - IPv4 和 IPv6 标头中区分服务字段(DS 字段)的定义废弃,并由RFC更新 3168 - 在 IP和RFC 3260中添加显式拥塞通知 (ECN) - Diffserv 的新术语和说明。
The IP protocol is mainly described in RFC 791 - Internet Protocol. However, this RFC is also updated by RFC 1349 - Type of Service in the Internet Protocol Suite, which was obsoleted by RFC 2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers, and which was updated by RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP and RFC 3260 - New Terminology and Clarifications for Diffserv.
正如您所看到的,所有这些标准有时都有点难以遵循。查找彼此相关的不同 RFC 的一个技巧是使用RFC-editor.org上提供的搜索功能。就 IP 而言,请考虑 RFC 791 是基本 RFC,所有其他内容都只是对该标准的更新和更改。当我们讨论这些较新的 RFC 更改的特定标头时,我们将更详细地讨论这些内容。 As you can see, all of these standards can get a little bit hard to follow at times. One tip for finding the different RFC's that are related to each other is to use the search functions available at RFC-editor.org. In the case of IP, consider that the RFC 791 is the basic RFC, and all of the other are simply updates and changes to that standard. We will discuss these more in detail when we get to the specific headers that are changed by these newer RFC's. 要记住的一件事是,有时 RFC 可能会被废弃(根本不使用)。通常这意味着 RFC 已经进行了如此彻底的更新,最好简单地替换整个内容。它也可能由于其他原因而变得过时。当 RFC 过时时,会向原始 RFC 添加一个指向新 RFC 的字段。 One thing to remember is, that sometimes, an RFC can be obsoleted (not used at all). Normally this means that the RFC has been so drastically updated and that it is better to simply replace the whole thing. It may also become obsolete for other reasons as well. When an RFC becomes obsoleted, a field is added to the original RFC that points to the new RFC instead. |
版本 - 位 0-3。这是二进制 IP 协议的版本号。IPv4称为0100,而IPv6称为0110。该字段一般不太用于过滤。RFC 791 中描述的版本是 IPv4。
Version - bits 0-3. This is a version number of the IP protocol in binary. IPv4 iscalled 0100, while IPv6 is called 0110. This field is generally not used for filtering very much. The version described in RFC 791 is IPv4.
IHL(互联网标头长度)- 位 4-7。该字段告诉我们 IP 标头在 32 位字中的长度。正如您所看到的,我们也在图像中以这种方式分割标题(每行 32 位)。由于选项字段的长度是可选的,因此如果没有该字段,我们永远无法绝对确定整个标头的长度。标头的最小长度为 5 个字。
IHL (Internet Header Length) - bits 4-7. This field tells us how long the IP header is in 32 bit words. As you can see, we have split the header up in this way (32 bits per line) in the image as well. Since the Options field is of optional length, we can never be absolutely sure of how long the whole header is, without this field. The minimum length of this of the header is 5 words.
服务类型、DSCP、ECN - 位 8-15。这是 IP 标头中最复杂的区域之一,原因很简单,它已经更新了 3 次。它的基本用法始终相同,但实现已经改变了几次。首先,该字段称为服务类型字段。该字段的位[0-2]称为优先字段。位[3]是正常/低延迟,位[4]是正常/高吞吐量,位[5]是正常/高可靠性,位[6-7]被保留以供将来使用。这仍然在很多硬件较旧的地方使用,并且仍然给互联网带来一些问题。其中,位 [6-7] 被指定设置为 0。在 ECN 更新(RFC 3168)中,我们开始使用这些保留位,因此将这些位设置为 0 以外的其他值。但许多旧的防火墙和路由器都内置了检查功能,检查这些位是否设置为 1,如果数据包设置为 1,则数据包将被丢弃。如今,这显然违反了 RFC,但除了抱怨之外,您对此无能为力。
Type of Service, DSCP, ECN - bits 8-15. This is one of the most complex areas of the IP header for the simple reason that it has been updated 3 times. It has always had the same basic usage, but the implementation has changed several times. First the field was called the Type of Service field. Bit [0-2] of the field was called the Precedence field. Bit [3] was Normal/Low delay, Bit [4] was Normal/High throughput, Bit [5] was Normal/High reliability and bit [6-7] was reserved for future usage. This is still used in a lot of places with older hardware, and it still causes some problems for the Internet. Among other things, bit [6-7] are specified to be set to 0. In the ECN updates (RFC 3168, we start using these reserved bits and hence set other values than 0 to these bits. But a lot of old firewalls and routers have built in checks looking if these bits are set to 1, and if the packets do, the packet is discarded. Today, this is clearly a violation of RFC's, but there is not much you can do about it, except to complain.
该字段的第二次迭代是该字段更改为 RFC 2474 中定义的 DS 字段。DS 代表差异化服务。根据此标准,位 [0-5] 是差分服务代码点 (DSCP),其余两位 [6-7] 仍然未使用。DSCP 字段的使用方式与之前使用 ToS 字段的方式几乎相同,用于标记如果所讨论的路由器在它们之间有任何区别,则应将该数据包视为哪种服务。一个重大变化是设备必须忽略未使用的位才能完全符合 RFC 2474,这意味着只要设备创建者遵循此 RFC,我们就可以摆脱之前解释的麻烦。
The second iteration of this field was when the field was changed into the DS field as defined in RFC 2474. DS stands for Differentiated Services. According to this standard bits [0-5] is Differentiated Services Code Point (DSCP) and the remaining two bits [6-7] are still unused. The DSCP field is pretty much used the same as in how the ToS field was used before, to mark what kind of service this packet should be treated like if the router in question makes any difference between them. One big change is that a device must ignore the unused bits to be fully RFC 2474 compliant, which means we get rid of the previous hassle as explained previously, as long as the device creators follow this RFC.
ToS 字段的第三次(也是最后一次)更改是,之前未使用的两个位用于 ECN(显式拥塞通知),如 RFC 3168 中所定义。ECN 用于让端节点了解路由器拥塞情况,在它实际开始丢弃数据包之前,以便终端节点能够在路由器实际需要开始丢弃数据之前减慢其数据传输速度。以前,丢弃数据是路由器告知其过载的唯一方式,并且端节点必须为每个丢弃的数据包缓慢重新启动,然后再次缓慢恢复速度。这两个位被命名为 ECT(支持 ECN 传输)和 CE(经历拥塞)代码点。
The third, and almost last, change of the ToS field was when the two, previously, unused bits were used for ECN (Explicit Congestion Notification), as defined in RFC 3168. ECN is used to let the end nodes know about a routers congestion, before it actually starts dropping packets, so that the end nodes will be able to slow down their data transmissions, before the router actually needs to start dropping data. Previously, dropping data was the only way that a router had to tell that it was overloaded, and the end nodes had to do a slow restart for each dropped packet, and then slowly gather up speed again. The two bits are named ECT (ECN Capable Transport) and CE (Congestion Experienced) codepoints.
整个混乱的最后一个迭代是 RFC 3260,它为 DiffServ 系统的使用提供了一些新的术语和说明。除了术语之外,它不涉及太多新的更新或更改。RFC 还用于澄清开发人员之间讨论的一些要点。
The final iteration of the whole mess is RFC 3260 which gives some new terminology and clarifications to the usage of the DiffServ system. It doesn't involve too many new updates or changes, except in the terminology. The RFC is also used to clarify some points that were discussed between developers.
总长度 - 位 16 - 31。该字段告诉我们数据包有多大(以八位字节为单位),包括标头和所有内容。单个数据包的最大大小为 65535 个八位位组或字节。最小数据包大小为 576 字节,不关心数据包是否分片到达。根据 RFC 791,仅在可以保证主机可以接收数据包的情况下,才建议发送大于此限制的数据包。但是,目前大多数网络都以 1500 字节数据包大小运行。这包括几乎所有以太网连接和大多数互联网连接。
Total Length - bits 16 - 31. This field tells us how large the packet is in octets, including headers and everything. The maximum size is 65535 octets, or bytes, for a single packet. The minimum packet size is 576 bytes, not caring if the packet arrives in fragments or not. It is only recommended to send larger packets than this limit if it can be guaranteed that the host can receive it, according to RFC 791. However, these days most networks runs at 1500 byte packet size. This includes almost all ethernet connections, and most Internet connections.
标识 - 位 32 - 46。该字段用于帮助重组分段数据包。
Identification - bits 32 - 46. This field is used in aiding the reassembly of fragmented packets.
标志 - 位 47 - 49。该字段包含一些与分段相关的杂项标志。第一个位被保留,但仍然没有使用,并且必须设置为0。如果数据包可能被分片,则第二个位设置为0,如果数据包不能被分片,则设置为1。如果这是最后一个片段,则第三个也是最后一个位可以设置为 0,如果同一数据包有更多片段,则可以设置为 1。
Flags - bits 47 - 49. This field contains a few miscellaneous flags pertaining to fragmentation. The first bit is reserved, but still not used, and must be set to 0. The second bit is set to 0 if the packet may be fragmented, and to 1 if it may not be fragmented. The third and last bit can be set to 0 if this was the last fragment, and 1 if there are more fragments of this same packet.
片段偏移 - 位 50 - 63。片段偏移字段显示此数据包属于数据报中的位置。片段以 64 位计算,第一个片段的偏移量为零。
Fragment Offset - bits 50 - 63. The fragment offset field shows where in the datagram that this packet belongs. The fragments are calculated in 64 bits, and the first fragment has offset zero.
生存时间 - 位 64 - 72。TTL 字段告诉我们数据包可以生存多长时间,或者更确切地说,它可以通过互联网经过多少“跳”。每个接触数据包的进程都必须从 TTL 字段中删除一个点,如果 TTL 达到零,则必须破坏并丢弃整个数据包。这基本上用作安全触发器,以便数据包不会最终陷入一台或多台主机之间的不可控循环中。破坏后,主机应向发送者返回 ICMP 超时消息。
Time to live - bits 64 - 72. The TTL field tells us how long the packet may live, or rather how many "hops" it may take over the Internet. Every process that touches the packet must remove one point from the TTL field, and if the TTL reaches zero, the whole packet must be destroyed and discarded. This is basically used as a safety trigger so that a packet may not end up in an uncontrollable loop between one or several hosts. Upon destruction the host should return an ICMP Time exceeded message to the sender.
协议 - 位 73 - 80。在该字段中指示下一层的协议。例如,这可以是 TCP、UDP 或 ICMP 等。所有这些号码均由互联网号码分配机构定义。所有号码都可以在互联网号码分配机构的主页上找到。
Protocol - bits 73 - 80. In this field the protocol of the next level layer is indicated. For example, this may be TCP, UDP or ICMP among others. All of these numbers are defined by the Internet Assigned Numbers Authority. All numbers can befound on their homepage Internet Assigned Numbers Authority.
标头校验和 - 位 81 - 96。这是数据包的 IP 标头的校验和。该字段在每个更改标头的主机上重新计算,这意味着数据包遍历的几乎每个主机,因为它们最常更改标头数据包 TTL 字段或其他字段。
Header checksum - bits 81 - 96. This is a checksum of the IP header of the packet.This field is recomputed at every host that changes the header, which means pretty much every host that the packet traverses over, since they most often change the packets TTL field or some other.
源地址 - 位 97 - 128。这是源地址字段。它通常写成 4 个八位位组,从二进制转换为十进制数字,中间有点。例如,127.0.0.1。该字段让接收者知道数据包来自哪里。
Source address - bits 97 - 128. This is the source address field. It is generally written in 4 octets, translated from binary to decimal numbers with dots in between. That is for example, 127.0.0.1. The field lets the receiver know where the packet came from.
目标地址 - 位 129 - 160。目标地址字段包含目标地址,令人惊讶的是,它的格式与源地址相同。
Destination address - bits 129 - 160. The destination address field contains the destination address, and what a surprise, it is formatted the same way as the source address.
选项 - 位 161 - 192 <> 478。选项字段不是可选的,正如它听起来的那样。实际上,这是 IP 标头中较复杂的字段之一。选项字段在标头中包含不同的可选设置,例如 Internet 时间戳、SACK 或记录路由路由选项。由于这些选项都是可选的,因此选项字段可以具有不同的长度,因此整个 IP 标头也可以具有不同的长度。然而,由于我们总是以 32 位字计算 IP 标头,因此我们必须始终以偶数(即 32 的倍数)结束标头。该字段可能包含零个或多个选项。
Options - bits 161 - 192 <> 478. The options field is not optional, as it may sound. Actually, this is one of the more complex fields in the IP header. The options field contains different optional settings within the header, such as Internet timestamps, SACK or record route route options. Since these options are all optional, the Options field can have different lengths, and hence the whole IP header. However, since we always calculate the IP header in 32 bit words, we must always end the header on an even number, that is the multiple of 32. The field may contain zero or more options.
选项字段以一个简短的 8 位字段开头,让我们知道数据包中使用了哪些选项。TCP 选项附录中的TCP 选项表中列出了所有选项。有关不同选项的更多信息,请阅读相应的 RFC。有关 IP 选项的更新列表,请查看Internet 号码分配机构。
The options field starts with a brief 8 bit field that lets us know which options are used in the packet. The options are all listed in the TCP Options table, in the TCP options appendix. For more information about the different options, read the proper RFC's. For an updated listing of the IP options, check at Internet Assigned Numbers Authority.
填充 - 位变量。这是一个填充字段,用于使标头以偶数 32 位边界结束。该字段必须始终设置为零,直到最后。
Padding - bits variable. This is a padding field that is used to make the header end at an even 32 bit boundary. The field must always be set to zeroes straight through to the end.
TCP 协议位于 IP 协议之上。它是一个有状态的协议,具有内置功能来查看数据是否被另一端主机正确接收。TCP协议的主要目标是保证数据可靠地接收和发送,保证数据在网际层和应用层之间正确传输,保证分组数据到达应用层的正确程序,保证数据的正确传输。以正确的顺序到达程序。所有这些都可以通过数据包的 TCP 标头实现。
The TCP protocol resides on top of the IP protocol. It is a stateful protocol and has built-in functions to see that the data was received properly by the other end host. The main goals of the TCP protocol is to see that data is reliably received and sent, that the data is transported between the Internet layer and Application layer correctly, and that the packet data reaches the proper program in the application layer, and that the data reaches the program in the right order. All of this is possible through the TCP headers of the packet.
TCP 协议将数据视为具有开始和停止信号的连续数据流。指示新流正在等待打开的信号在 TCP 中称为 SYN 三向握手,由一个设置了 SYN 位的数据包组成。然后另一端用 SYN/ACK 或 SYN/RST 进行应答,让客户端分别知道连接是被接受还是被拒绝。如果客户端收到 SYN/ACK 数据包,它会再次回复,这次是 ACK 数据包。至此,整个连接就建立起来了,可以发送数据了。在此初始握手期间,还将协商将在 TCP 连接的其余部分中使用的所有特定选项,例如 ECN、SACK 等。
The TCP protocol looks at data as an continuous data stream with a start and a stop signal. The signal that indicates that a new stream is waiting to be opened is called a SYN three-way handshake in TCP, and consists of one packet sent with the SYN bit set. The other end then either answers with SYN/ACK or SYN/RST to let the client know if the connection was accepted or denied, respectively. If the client receives an SYN/ACK packet, it once again replies, this time with an ACK packet. At this point, the whole connection is established and data can be sent. During this initial handshake, all of the specific options that will be used throughout the rest of the TCP connection is also negotiated, such as ECN, SACK, etcetera.
当数据流处于活动状态时,我们有进一步的机制来查看数据包实际上已被另一端正确接收。这是TCP的可靠性部分。这是通过使用数据包中的序列号以简单的方式完成的。每次发送数据包时,我们都会为序列号赋予一个新值,当另一端收到数据包时,它会向数据发送方发送一个 ACK 数据包。ACK 数据包确认数据包已正确接收。序列号还确保数据包以良好的顺序插入到数据流中。
While the datastream is alive, we have further mechanisms to see that the packets are actually received properly by the other end. This is the reliability part of TCP. This is done in a simple way, using a Sequence number in the packet. Every time we send a packet, we give a new value to the Sequence number, and when the other end receives the packet, it sends an ACK packet back to the data sender. The ACK packet acknowledges that the packet was received properly. The sequence number also sees to it that the packet is inserted into the data stream in a good order.
连接关闭后,可以通过从任一端点发送 FIN 数据包来完成。然后另一端通过发送 FIN/ACK 数据包进行响应。FIN发送端就不能再发送任何数据,但另一端仍然可以完成数据发送。一旦第二个端点希望完全关闭连接,它就会向最初关闭的端点发送 FIN 数据包,而另一个端点则回复 FIN/ACK 数据包。整个过程完成后,连接就会正确断开。
Once the connection is closed, this is done by sending a FIN packet from either end-point. The other end then responds by sending a FIN/ACK packet. The FIN sending end can then no longer send any data, but the other end-point can still finish sending data. Once the second end-point wishes to close the connection totally, it sends a FIN packet back to the originally closing end-point, and the other end-point replies with a FIN/ACK packet. Once this whole procedure is done, the connection is torn down properly.
正如您稍后将看到的,TCP 标头也包含校验和。校验和由数据包的简单散列组成。通过这个哈希值,我们可以相当高精度地查看数据包在主机之间传输期间是否以任何方式被损坏。
As you will also later see, the TCP headers contain a checksum as well. The checksum consists of a simple hash of the packet. With this hash, we can with rather high accuracy see if a packet has been corrupted in any way during transit between the hosts.
TCP 标头必须能够执行上述所有任务。我们已经解释了某些标头的使用时间和地点,但还有其他一些领域我们还没有深入探讨。下面您可以看到完整的 TCP 标头集的图像。如您所见,它的格式为每行 32 位字。
The TCP headers must be able to perform all of the tasks above. We have already explained when and where some of the headers are used, but there are still other areas that we haven't touched very deeply at. Below you see an image of the complete set of TCP headers. It is formatted in 32 bit words per row, as you can see.
源端口 - 位 0 - 15。这是数据包的源端口。源端口最初直接绑定到发送系统上的进程。今天,我们在 IP 地址以及目标和源端口之间使用哈希来实现这种唯一性,我们可以将其绑定到单个应用程序或程序。
Source port - bit 0 - 15. This is the source port of the packet. The source port was originally bound directly to a process on the sending system. Today, we use a hash between the IP addresses, and both the destination and source ports to achieve this uniqueness that we can bind to a single application or program.
目标端口 - 位 16 - 31。这是 TCP 数据包的目标端口。正如源端口一样,它最初直接绑定到接收系统上的进程。如今,我们使用了哈希值,这使得我们可以同时拥有更多的开放连接。当收到数据包时,在返回原始发送主机的回复中,目标端口和源端口会颠倒过来,因此目标端口现在是源端口,源端口是目标端口。
Destination port - bit 16 - 31. This is the destination port of the TCP packet. Just as with the source port, this was originally bound directly to a process on the receiving system. Today, a hash is used instead, which allows us to have more open connections at the same time. When a packet is received, the destination and source ports are reversed in the reply back to the originally sending host, so that destination port is now source port, and source port is destination port.
序列号 - 位 32 - 63。序列号字段用于在每个 TCP 数据包上设置一个编号,以便 TCP 流可以正确排序(例如,数据包以正确的顺序结束)。然后,序列号在 ACK 字段中返回,以确认数据包已正确接收。
Sequence Number - bit 32 - 63. The sequence number field is used to set a number on each TCP packet so that the TCP stream can be properly sequenced (e.g., the packets winds up in the correct order). The Sequence number is then returned in the ACK field to ackonowledge that the packet was properly received.
确认编号 - 位 64 - 95。当我们确认主机收到的特定数据包时,将使用此字段。例如,我们收到一个设置了一个序列号的数据包,如果该数据包一切正常,我们会回复一个 ACK 数据包,其中确认号设置为与原始序列号相同。
Acknowledgment Number - bit 64 - 95. This field is used when we acknowledge a specific packet a host has received. For example, we receive a packet with one Sequence number set, and if everything is okey with the packet, we reply with an ACK packet with the Acknowledgment number set to the same as the original Sequence number.
数据偏移 - 位 96 - 99。该字段指示 TCP 标头的长度以及数据包的数据部分实际开始的位置。它设置为 4 位,并以 32 位字测量 TCP 标头。即使设置了不同的选项,标头也应始终以偶数 32 位边界结束。这要归功于 TCP 标头最末尾的填充字段。
Data Offset - bit 96 - 99. This field indicates how long the TCP header is, and where the Data part of the packet actually starts. It is set with 4 bits, and measures the TCP header in 32 bit words. The header should always end at an even 32 bit boundary, even with different options set. This is possible thanks to the Padding field at the very end of the TCP header.
保留 - 位 100 - 103。这些位保留供将来使用。在 RFC 793 中,这还包括 CWR 和 ECE 位。根据 RFC 793 位 100-105(即,此字段以及 CWR 和 ECE 字段)必须设置为零才能完全兼容。后来,当我们开始引入ECN时,这引起了很多麻烦,因为许多互联网设备(例如防火墙和路由器)在设置它们后会丢弃数据包。截至撰写本文时,情况仍然如此。
Reserved - bit 100 - 103. These bits are reserved for future usage. In RFC 793 this also included the CWR and ECE bits. According to RFC 793 bit 100-105 (i.e., this and the CWR and ECE fields) must be set to zero to be fully compliant. Later on, when we started introducing ECN, this caused a lot of troubles because a lot of Internet appliances such as firewalls and routers dropped packets with them set. This is still true as of writing this.
CWR - 位 104。该位是在 RFC 3268 中添加的,并由 ECN 使用。CWR是Congestion Window Decred的缩写,用于数据发送端通知接收端拥塞窗口已经减小。当拥塞窗口减少时,我们在每个时间单位发送更少的数据,以便能够应对总网络负载。
CWR - bit 104. This bit was added in RFC 3268 and is used by ECN. CWR stands for Congestion Window Reduced, and is used by the data sending part to inform the receiving part that the congestion window has been reduced. When the congestion window is reduced, we send less data per timeunit, to be able to cope with the total network load.
ECE - 位 105。该位也是随 RFC 3268 添加的,并由 ECN 使用。ECE 代表 ECN 回声。接收方主机上的 TCP/IP 堆栈使用它来让发送方主机知道它已收到 CE 数据包。同样的事情也适用于此,对于 CWR 位,它最初是保留字段的一部分,因此,如果这些字段包含除零以外的任何内容,某些网络设备将简单地丢弃数据包。不幸的是,对于许多电器来说,实际上仍然如此。
ECE - bit 105. This bit was also added with RFC 3268 and is used by ECN. ECE stands for ECN Echo. It is used by the TCP/IP stack on the receiver host to let the sending host know that it has received an CE packet. The same thing applies here, as for the CWR bit, it was originally a part of the reserved field and because of this, some networking appliances will simply drop the packet if these fields contain anything else than zeroes. This is actually still true for a lot of appliances unfortunately.
URG - 位 106。该字段告诉我们是否应该使用紧急指针字段。如果设置为 0,则不使用紧急指针,如果设置为 1,则使用紧急指针。
URG - bit 106. This field tells us if we should use the Urgent Pointer field or not. If set to 0, do not use Urgent Pointer, if set to 1, do use Urgent pointer.
ACK - 位 107。该位设置为数据包,表示这是对我们收到的另一个包含数据的数据包的回复。始终发送确认数据包以表明我们实际上已收到数据包,并且它不包含任何错误。如果该位被设置,原始数据发送方将检查确认号以查看哪个数据包被实际确认,然后将其从缓冲区中转储。
ACK - bit 107. This bit is set to a packet to indicate that this is in reply to another packet that we received, and that contained data. An Acknowledgment packet is always sent to indicate that we have actually received a packet, and that it contained no errors. If this bit is set, the original data sender will check the Acknowledgment Number to see which packet is actually acknowledged, and then dump it from the buffers.
PSH - 位 108。PUSH 标志用于告诉任何中间主机上的 TCP 协议将数据发送到实际用户,包括接收主机上的 TCP 实现。这将推送所有数据,无论已推送的 TCP 窗口在何处或多少。
PSH - bit 108. The PUSH flag is used to tell the TCP protocol on any intermediate hosts to send the data on to the actual user, including the TCP implementation on the receiving host. This will push all data through, unregardless of where or how much of the TCP Window that has been pushed through yet.
RST - 位 109。设置 RESET 标志以告诉另一端拆除 TCP 连接。这是在几种不同的情况下完成的,主要原因是连接由于某种原因而崩溃,如果连接不存在,或者数据包在某种程度上是错误的。
RST - bit 109. The RESET flag is set to tell the other end to tear down the TCP connection. This is done in a couple of different scenarios, the main reasons being that the connection has crashed for some reason, if the connection does not exist, or if the packet is wrong in some way.
SYN - 位 110。SYN(或同步序列号)在连接的初始建立期间使用。它在连接的两个实例中设置,即打开连接的初始数据包和回复 SYN/ACK 数据包。它永远不应该在这些实例之外使用。
SYN - bit 110. The SYN (or Synchronize sequence numbers) is used during the initial establishment of a connection. It is set in two instances of the connection, the initial packet that opens the connection, and the reply SYN/ACK packet. It should never be used outside of those instances.
FIN - 位 111。FIN 位指示发送 FIN 位的主机没有更多数据要发送。当另一端看到 FIN 位时,会回复 FIN/ACK。完成此操作后,最初发送 FIN 位的主机将无法再发送任何数据。但另一端可以继续发送数据,直到发送完毕,然后会发回FIN数据包,并等待最终的FIN/ACK,之后连接将转为CLOSED状态。
FIN - bit 111. The FIN bit indicates that the host that sent the FIN bit has no more data to send. When the other end sees the FIN bit, it will reply with a FIN/ACK. Once this is done, the host that originally sent the FIN bit can no longer send any data. However, the other end can continue to send data until it is finished, and will then send a FIN packet back, and wait for the final FIN/ACK, after which the connection is sent to a CLOSED state.
窗口 - 位 112 - 127。接收主机使用窗口字段来告诉发送方接收方当前允许多少数据。这是通过发回 ACK 来完成的,其中包含我们要确认的序列号,然后窗口字段包含发送主机在接收下一个 ACK 数据包之前可以使用的最大接受序列号。下一个ACK数据包将更新发送方可以使用的接受窗口。
Window - bit 112 - 127. The Window field is used by the receiving host to tell the sender how much data the receiver permits at the moment. This is done by sending an ACK back, which contains the Sequence number that we want to acknowledge, and the Window field then contains the maximum accepted sequence numbers that the sending host can use before he receives the next ACK packet. The next ACK packet will update accepted Window which the sender may use.
校验和 - 位 128 - 143。该字段包含整个 TCP 标头的校验和。它是头部中每个16位字的反码和的反码。如果标头未在 16 位边界上结束,则附加位将设置为零。计算校验和时,校验和字段设置为零。校验和还包含一个 96 位伪标头,其中包含目标地址、源地址、协议和 TCP 长度。这是为了额外的安全性。
Checksum - bit 128 - 143. This field contains the checksum of the whole TCP header. It is a one's complement of the one's complement sum of each 16 bit word in the header. If the header does not end on a 16 bit boundary, the additional bits are set to zero. While the checksum is calculated, the checksum field is set to zero. The checksum also covers a 96 bit pseudoheader containing the Destination-, Source-address, protocol, and TCP length. This is for extra security.
紧急指针 - 位 144 - 159。这是一个指向被视为紧急的数据末尾的指针。如果连接中有重要数据需要接收端尽快处理,发送方可以设置URG标志并设置紧急指针来指示紧急数据在哪里结束。
Urgent Pointer - bit 144 - 159. This is a pointer that points to the end of the data which is considered urgent. If the connection has important data that should be processed as soon as possible by the receiving end, the sender can set the URG flag and set the Urgent pointer to indicate where the urgent data ends.
选项 - 位 160 - **。选项字段是一个可变长度字段,包含我们可能想要使用的可选标头。基本上,该字段始终包含 3 个子字段。初始字段告诉我们选项字段的长度,第二个字段告诉我们使用了哪些选项,然后我们就有了实际的选项。所有 TCP 选项的完整列表可以在TCP 选项中找到。
Options - bit 160 - **. The Options field is a variable length field and contains optional headers that we may want to use. Basically, this field contains 3 subfields at all times. An initial field tells us the length of the Options field, a second field tells us which options are used, and then we have the actual options. A complete listing of all the TCP Options can be found in TCP options.
填充 - 位**。填充字段填充 TCP 标头,直到整个标头以 32 位边界结束。这可确保数据包的数据部分从 32 位边界开始,并且数据包中不会丢失任何数据。填充始终仅由零组成。
Padding - bit **. The padding field pads the TCP header until the whole header ends at a 32-bit boundary. This ensures that the data part of the packet begins on a 32-bit boundary, and no data is lost in the packet. The padding always consists of only zeros.
用户数据报协议 (UDP) 是 IP 协议之上的一个非常基本且简单的协议。它的开发是为了允许非常简单的数据传输,无需任何类型的错误检测,并且它是无状态的。然而,它非常适合查询/响应类型的应用程序,例如 DNS 等,因为我们知道,除非我们从 DNS 服务器获得答复,否则查询会在某个地方丢失。有时,也可能值得使用 UDP 协议而不是 TCP,例如当我们只想进行错误/丢失检测但不关心数据包的排序时。这消除了来自 TCP 协议的一些开销。我们还可以做其他事情,在 UDP 之上制定我们自己的协议,仅包含排序,但不包含错误或丢失检测。
The User Datagram Protocol (UDP) is a very basic and simple protocol on top of the IP protocol. It was developed to allow for very simple data transmission without any error detection of any kind, and it is stateless. However, it is very well fit for query/response kind of applications, such as for example DNS, et cetera, since we know that unless we get a reply from the DNS server, the query was lost somewhere. Sometimes it may also be worth using the UDP protocol instead of TCP, such as when we want only error/loss detection but don't care about sequencing of the packets. This removes some overhead that comes from the TCP protocol. We may also do the other thing around, make our own protocol on top of UDP that only contains sequencing, but no error or loss detection.
UDP 协议在RFC 768 - 用户数据报协议中指定。这是一个非常简短的 RFC,非常适合像这样的简单协议。
The UDP protocol is specified in RFC 768 - User Datagram Protocol. It is a very short and brief RFC, which fits a simple protocol like this very well.
UDP报头可以说包含了一个非常基本且简化的TCP报头。它包含目标端口、源端口、标头长度和校验和,如下图所示。
The UDP header can be said to contain a very basic and simplified TCP header. It contains destination-, source-ports, header length and a checksum as seen in the image below.
源端口 - 位 0-15。这是数据包的源端口,描述了应答数据包应发送到的位置。如果不适用,实际上可以将其设置为零。例如,有时我们不需要回复数据包,然后可以将数据包设置为源端口零。在大多数实现中,它被设置为某个端口号。
Source port - bit 0-15. This is the source port of the packet, describing where a reply packet should be sent. This can actually be set to zero if it doesn't apply. For example, sometimes we don't require a reply packet, and the packet can then be set to source port zero. In most implementations, it is set to some port number.
目标端口 - 位 16-31。数据包的目的端口。这对于所有数据包都是必需的,而不是数据包的源端口。
Destination port - bit 16-31. The destination port of the packet. This is required for all packets, as opposed to the source port of a packet.
长度 - 位 32-47。长度字段指定整个数据包的长度(以八位字节为单位),包括标头和数据部分。最短的数据包长度可为 8 个八位位组。
Length - bit 32-47. The length field specifies the length of the whole packet in octets, including header and data portions. The shortest possible packet can be 8 octets long.
校验和 - 位 48-63。校验和与 TCP 标头中使用的校验和相同,只是它包含不同的数据集。换句话说,它是IP报头部分、整个UDP报头、UDP数据的补码和的补码,并在必要时在末尾补零。
Checksum - bit 48-63. The checksum is the same kind of checksum as used in the TCP header, except that it contains a different set of data. In other words, it is a one's complement of the one's complement sum of parts of the IP header, the whole UDP header, theUDP data and padded with zeroes at the end when necessary.
ICMP 消息用于主机到主机或主机到网关之间的基本错误报告。在网关到网关之间,通常应使用称为网关到网关协议 (GGP) 的协议来进行错误报告。正如我们已经讨论过的,IP 协议并不是为完美的错误处理而设计的,但 ICMP 消息解决了这些问题的某些部分。从一个角度来看,最大的问题是 ICMP 消息的标头相当复杂,并且各个消息之间略有不同。然而,大多数时候从过滤的角度来看这并不是一个大问题。
ICMP messages are used for a basic kind of error reporting between host to host, or host to gateway. Between gateway to gateway, a protocol called Gateway to Gateway protocol (GGP) should normally be used for error reporting. As we have already discussed, the IP protocol is not designed for perfect error handling, but ICMP messages solves some parts of these problems. The big problem from one standpoint is that the headers of the ICMP messages are rather complicated, and differ a little bit from message to message. However, this will not be a big problem from a filtering standpoint most of the time.
基本形式是消息包含标准IP头、类型、代码和校验和。所有 ICMP 消息都包含这些字段。类型指定该数据包是什么类型的错误或回复消息,例如目的地不可达、回显、回显回复或重定向消息。如有必要,代码字段指定更多信息。如果数据包的类型为“目的地不可达”,则此代码字段上有多个可能的值,例如网络不可达、主机不可达或端口不可达。校验和只是整个数据包的校验和。
The basic form is that the message contains the standard IP header, type, code and a checksum. All ICMP messages contains these fields. The type specifies what kind of error or reply message this packet is, such as for example destination unreachable, echo, echo reply, or redirect message. The code field specifies more information, if necessary. If the packet is of type destination unreachable, there are several possible values on this code field such as network unreachable, host unreachable, or port unreachable. The checksum is simply a checksum for the whole packet.
您可能已经注意到,我明确提到了 ICMP 数据包的 IP 标头。这样做是因为实际的 IP 标头是 ICMP 数据包的组成部分,并且 ICMP 协议在某种意义上与 IP 协议处于同一级别。ICMP 确实使用 IP 协议,就好像它是更高级别的协议一样,但同时又不是。ICMP 是IP 的一个组成部分,并且ICMP 必须在每个IP 实现中实现。
As you may have noticed, I mentioned the IP header explicitly for the ICMP packet. This was done since the actual IP header is an integral part of the ICMP packet, and the ICMP protocol lives on the same level as the IP protocol in a sense. ICMP does use the IP protocol as if it where a higher level protocol, but at the same time not. ICMP is an integral part of IP, and ICMP must be implemented in every IP implementation.
如前所述,不同 ICMP 类型的标头略有不同。大多数 ICMP 类型都可以按其标头进行分组。因此,我们将首先讨论基本标头形式,然后查看应讨论的每组类型的具体细节。
As already explained, the headers differs a little bit from ICMP type to ICMP type. Most of the ICMP types are possible to group by their headers. Because of this, we will discuss the basic header form first, and then look at the specifics for each group of types that should be discussed.
所有数据包都包含本章前面讨论的 IP 标头中的一些基本值。之前已经对标题进行了一定的讨论,因此这只是标题的简短列表,以及一些关于它们的注释。
All packets contain some basic values from the IP headers discussed previously in this chapter. The headers have previously been discussed at some length, so this is just a short listing of the headers, with a few notes about them.
版本 - 应始终设置为 4。
Version - This should always be set to 4.
Internet 标头长度 - 32 位字中的标头长度。
Internet Header Length - The length of the header in 32 bit words.
服务类型 - 参见上文。该值应设置为 0,因为这是根据RFC 792 - Internet Control Message Protocol 的唯一合法设置。
Type of Service - See above. This should be set to 0, as this is the only legit setting according to RFC 792 - Internet Control Message Protocol.
总长度 - 数据包的标头和数据部分的总长度,以八位位组计算。
Total Length - Total length of the header and data portion of the packet, counted in octets.
标识、标志和片段偏移量 - 从 IP 协议中剥离。
Identification , Flags and Fragment offsets - Ripped from the IP protocol.
生存时间 - 该数据包将存活多少跳。
Time To Live - How many hops this packet will survive.
协议 - 正在使用哪个版本的 ICMP(应始终为 1)。
Protocol - which version of ICMP is being used (should always be 1).
标头校验和 - 请参阅 IP 说明。
Header Checksum - See the IP explanation.
源地址 - 发送数据包的源地址。这并不完全正确,因为数据包可以有另一个源地址,而不是位于相关机器上的源地址。如果是这样,将注明可以产生此效果的 ICMP 类型。
Source Address - The source address from whom the packet was sent. This is not entirely true, since the packet can have another source address, than that which is located on the machine in question. The ICMP types that can have this effect will be noted if so.
目标地址 - 数据包的目标地址。
Destination Address - The destination address of the packet.
还有一些所有 ICMP 类型都使用的新标头。新的标题如下,这次还有一些关于它们的注释:
There are also a couple of new headers that are used by all of the ICMP types. The new headers are as follows, this time with a few more notes about them:
类型 - 类型字段包含数据包的 ICMP 类型。这对于不同的 ICMP 类型总是不同的。例如,ICMP 目标不可达数据包将设置为类型 3。有关不同 ICMP 类型的完整列表,请参阅ICMP 类型附录。该字段总共包含 8 位。
Type - The type field contains the ICMP type of the packet. This is always different from ICMP type to type. For example ICMP Destination Unreachable packets will have a type 3 set to it. For a complete listing of the different ICMP types, see the ICMP types appendix. This field contains 8 bits total.
代码 - 所有 ICMP 类型也可以包含不同的代码。有些类型只有一个代码,而其他类型则有多个可以使用的代码。例如,ICMP 目标无法到达(类型 3)可以至少设置代码 0、1、2、3、4 或 5。每个代码在该上下文中都有不同的含义。有关不同代码的完整列表,请参阅ICMP 类型附录。该字段总共有 8 位长度。我们将在本节后面更详细地讨论每种类型的不同代码。
Code - All ICMP types can contain different codes as well. Some types only have a single code, while others have several codes that they can use. For example, the ICMP Destination Unreachable (type 3) can have at least code 0, 1, 2, 3, 4 or 5 set. Each code has a different meaning in that context then. For a complete listing of the different codes, see the ICMP types appendix. This field is 8 bits in length, total. We will discuss the different codes a little bit more in detail for each type later on in this section.
校验和 - 校验和是一个 16 位字段,包含从 ICMP 类型开始向下的标头的补码。计算校验和时,校验和字段应设置为零。
Checksum - The Checksum is a 16 bit field containing a one's complement of the ones complement of the headers starting with the ICMP type and down. While calculating the checksum, the checksum field should be set to zero.
此时,不同数据包的标头也开始看起来不同。我们将一一描述最常见的 ICMP 类型,并简要讨论其标头和不同的代码。
At this point the headers for the different packets start to look different also. We will describe the most common ICMP Types one by one, with a brief discussion of its headers and different codes.
我选择在这里同时讨论 ICMP 回显数据包的回复和请求,因为它们彼此密切相关。第一个区别是回显请求是类型 8,而回显回复是类型 0。当主机收到类型 8 时,它会回复类型 0。
I have chosen to speak about both the reply and the request of the ICMP echo packets here since they are so closely related to each other. The first difference is that the echo request is type 8, while echo reply is type 0. When a host receives a type 8, it replies with a type 0.
当发送回复时,源地址和目标地址也会交换位置。完成这两项更改后,将重新计算校验和并发送回复。这两种类型只有一个代码,它们始终设置为 0。
When the reply is sent, the source and destination addresses switch places as well. After both of those changes has been done, the checksum is recomputed, and the reply is sent. There is only one code for both of these types, they are always set to 0.
标识符 - 这是在请求数据包中设置的,并在回复中回显,以便能够将不同的 ping 请求和回复保持在一起。
Identifier - This is set in the request packet, and echoed back in the reply, to be able to keep different ping requests and replies together.
序列号 - 每个主机的序列号,通常从 1 开始,每个数据包加 1。
Sequence number - The sequence number for each host, generally this starts at 1 and is incremented by 1 for each packet.
数据包还包含数据部分。默认情况下,数据部分通常为空,但它可以包含用户指定数量的随机数据。
The packets also contains a data part. Per default, the data part is generally empty, but it can contain a userspecified amount of random data.
图像中看到的前三个字段与前面描述的相同。目的地不可达类型有 16 个可以使用的基本代码,如下列表所示。
The first three fields seen in the image are the same as previously described. The Destination Unreachable type has 16 basic codes that can be used, as seen below in the list.
代码 0 - 网络无法访问 - 告诉您当前是否无法访问特定网络。
Code 0 - Network unreachable - Tells you if a specific network is currently unreachable.
代码 1 - 主机无法访问 - 告诉您当前是否无法访问特定主机。
Code 1 - Host unreachable - Tells you if a specific host is currently unreachable.
代码 2 - 协议无法访问 - 此代码告诉您当前是否无法访问特定协议(tcp、udp 等)。
Code 2 - Protocol unreachable - This code tells you if a specific protocol (tcp, udp, etc) can not be reached at the moment.
代码 3 - 端口无法访问 - 如果端口(ssh、http、ftp-data 等)无法访问,您将收到此消息。
Code 3 - Port unreachable - If a port (ssh, http, ftp-data, etc) is not reachable, you will get this message.
代码 4 - 需要分段并设置 DF - 如果需要对数据包进行分段才能传送,但在数据包中设置了“不分段”位,则网关将返回此消息。
Code 4 - Fragmentation needed and DF set - If a packet needs to be fragmented to be delivered, but the Do not fragment bit is set in the packet, the gateway will return this message.
代码 5 - 源路由失败 - 如果源路由由于某种原因失败,则返回此消息。
Code 5 - Source route failed - If a source route failed for some reason, this message is returned.
代码 6 - 目标网络未知 - 如果没有到特定网络的路由,则返回此消息。
Code 6 - Destination network unknown - If there is no route to a specific network, this message is returned.
代码 7 - 目标主机未知 - 如果没有到特定主机的路由,则返回此消息。
Code 7 - Destination host unknown - If there is no route to a specific host, this message is returned.
代码 8 - 源主机已隔离(已过时) - 如果主机已隔离,则应返回此消息。该代码今天已过时。
Code 8 - Source host isolated (obsolete) - If a host is isolated, this message should be returned. This code is obsoleted today.
代码 9 - 目标网络被管理禁止 - 如果网络在网关处被阻止并且您的数据包因此无法到达该网络,您应该取回此 ICMP 代码。
Code 9 - Destination network administratively prohibited - If a network was blocked at a gateway and your packet was unable to reach it because of this, you should get this ICMP code back.
代码 10 - 目标主机被管理禁止 - 如果您由于管理禁止(例如,路由管理)而无法到达主机,您将收到此消息。
Code 10 - Destination host administratively prohibited - If you where unable to reach a host because it was administratively prohibited (e.g., routing administration), you will get this message back.
代码 11 - TOS 网络无法访问 - 如果由于数据包中的 TOS 设置 错误而无法访问网络 ,则将生成此代码作为返回数据包。
Code 11 - Network unreachable for TOS - If a network was unreachable because of a bad TOS setting in your packet, this code will be generated as a return packet.
代码 12 - 因 TOS 无法到达主机 - 如果您的数据包因数据包的 TOS 而无法到达主机,则这是您收到的消息。
Code 12 - Host unreachable for TOS - If your packet was unable to reach a host because of the TOS of the packet, this is the message you get back.
代码 13 - 通过过滤在管理上禁止通信 - 如果数据包被某种过滤(例如防火墙)禁止,我们会得到代码 13。
Code 13 - Communication administratively prohibited by filtering - If the packet was prohibited by some kind of filtering (e.g., firewalling), we get a code 13 back.
代码 14 - 主机优先级冲突 - 由第一跳路由器发送,以通知连接的主机,通知主机特定目标/源组合不允许使用优先级。
Code 14 - Host precedence violation - This is sent by the first hop router to notify a connected host, to notify the host that the used precedence is not permitted for a specific destination/source combination.
代码 15 - 优先级截止生效 - 如果第一跳路由器收到的数据报中设置的优先级太低,则第一跳路由器可能会将此消息发送到主机。
Code 15 - Precedence cutoff in effect - The first hop router may send this message to a host if the datagram it received had a too low precedence level set in it.
除此之外,它还包含一个小的“数据”部分,它应该是整个互联网标头(IP标头)和原始IP数据报的64位。如果下一级协议包含任何端口等,则假定这些端口应在额外的 64 位中可用。
On top of this, it also contains a small "data" part, which should be the whole Internet header (IP header) and 64 bits of the original IP datagram. If the next level protocol contains any ports, etc, it is assumed that the ports should be available in the extra 64 bits.
可以发送源抑制数据包,以告诉数据包或数据包流的原始源在继续发送数据时放慢速度。请注意,数据包所经过的网关或目标主机也可以保持安静并默默地丢弃数据包,而不是发送任何源抑制数据包。
A source quench packet can be sent to tell the originating source of a packet or stream of packets to slow down when continuing to send data. Note that gateway or destination host that the packets traverses can also be quiet and silently discard the packets, instead of sending any source quench packets.
除了数据部分外,该数据包不包含任何额外的标头,数据部分包含互联网标头以及原始数据报的 64 位。这用于将源抑制消息与当前正在通过网关发送数据或向目标主机发送数据的正确进程进行匹配。
This packet contains no extra header except the data portion, which contains the internet header plus 64 bits of the original data datagram. This is used to match the source quench message to the correct process, which is currently sending data through the gateway or to the destination host.
所有源抑制数据包的 ICMP 类型均设置为 4。除了 0 之外,它们没有任何代码。
All source quench packets have their ICMP types set to 4. They have no codes except 0.
如今,有几种新的可能方法可以通知发送和接收主机网关或目标主机过载。例如,一种方法是 ECN(显式拥塞通知)系统。 Today, there are a couple of new possible ways of notifying the sending and receiving host that a gateway or destination host is overloaded. One way for example is the ECN (Explicit Congestion Notification) system. |
ICMP 重定向类型在单一情况下发送。考虑一下,您有一个网络 (192.168.0.0/24),其上有多个客户端和主机,以及两个网关。一个通往 10.0.0.0/24 网络的网关,以及一个通往 Internet 其余部分的默认网关。现在考虑 192.168.0.0/24 网络上的一台主机是否没有设置到 10.0.0.0/24 的路由,但设置了默认网关。它向默认网关发送一个数据包,默认网关当然知道 10.0.0.0/24 网络。默认网关可以推断,将数据包直接发送到 10.0.0.0/24 网关会更快,因为数据包将在同一接口上进入和离开网关。因此,默认网关将向主机发送单个 ICMP 重定向数据包,告知其真实网关,然后将该数据包发送到 10.0.0.0/24 网关。
The ICMP Redirect type is sent in a single case. Consider this, you have a network (192.168.0.0/24) with several clients and hosts on it, and two gateways. One gateway to a 10.0.0.0/24 network, and a default gateway to the rest of the Internet. Now consider if one of the hosts on the 192.168.0.0/24 network has no route set to 10.0.0.0/24, but it has the default gateway set. It sends a packet to the default gateway, which of course knows about the 10.0.0.0/24 network. The default gateway can deduce that it is faster to send the packet directly to the 10.0.0.0/24 gateway since the packet will enter and leave the gateway on the same interface. The default gateway will hence send out a single ICMP Redirect packet to the host, telling it about the real gateway, and then sending the packet on to the 10.0.0.0/24 gateway. The host will now know about the closest 10.0.0.0/24 gateway, and hopefully use it in the future.
重定向类型的主要标头是网关互联网地址字段。该字段告诉主机有关真正应该使用的正确网关的信息。该数据包还包含原始数据包的 IP 标头以及原始数据包中的前 64 位数据,用于将其连接到发送数据的正确进程。
The main header of the Redirect type is the Gateway Internet Address field. This field tells the host about the proper gateway, which should really be used. The packet also contains the IP header of the original packet, and the 64 first bits of data in the original packet, which is used to connect it to the proper process sending the data.
重定向类型也有 4 个不同的代码,如下所示。
The Redirect type has 4 different codes as well, these are the following.
代码 0 - 网络重定向 - 仅用于整个网络的重定向(例如上面的示例)。
Code 0 - Redirect for network - Only used for redirects for a whole network (e.g., the example above).
代码 1 - 主机重定向 - 仅用于特定主机的重定向(例如,主机路由)。
Code 1 - Redirect for host - Only used for redirects of a specific host (e.g., a host route).
代码 2 - TOS 和网络的重定向 - 仅用于特定服务类型和整个网络的重定向。用作代码 0,但也基于 TOS。
Code 2 - Redirect for TOS and network - Only used for redirects of a specific Type of Service and to a whole network. Used as code 0, but also based on the TOS.
代码 3 - TOS 和主机的重定向 - 仅用于特定服务类型和特定主机的重定向。用作代码 1,但也基于 TOS。
Code 3 - Redirect for TOS and host - Only used for redirects of a specific Type of Service and to a specific host. Used as code 1, but also based on the TOS in other words.
TTL 等于 0 ICMP 类型也称为超时消息,类型设置为 11,并且有 2 个可用的 ICMP 代码。如果在通过网关传输或在目的主机上进行分片重组期间,TTL 字段达到 0,则数据包必须被丢弃。为了通知发送主机此问题,我们可以发送 TTL 等于 0 的 ICMP 数据包。如有必要,发送方可以提高发送到该目的地的传出数据包的 TTL。
The TTL equals 0 ICMP type is also known as Time Exceeded Message and has type 11 set to it, and has 2 ICMP codes available. If the TTL field reaches 0 during transit through a gateway or fragment reassembly on the destination host, the packet must be discarded. To notify the sending host of this problem, we can send a TTL equals 0 ICMP packet. The sender can then raise the TTL of outgoing packets to this destination if necessary.
该数据包仅包含数据包的额外数据部分。数据字段包含互联网头加上IP数据包的64位数据,以便另一端可以将数据包匹配到正确的进程。如前所述,TTL等于0类型可以有两个代码。
The packet only contains the extra data portion of the packet. The data field contains the Internet header plus 64 bits of the data of the IP packet, so that the other end may match the packet to the proper process. As previously mentioned, the TTL equals 0 type can have two codes.
代码 0 - 传输期间 TTL 等于 0 - 如果在网关转发数据包时原始数据包 TTL 达到 0,则将其发送到发送主机。
Code 0 - TTL equals 0 during transit - This is sent to the sending host if the original packet TTL reached 0 when it was forwarded by a gateway.
代码 1 - 重组期间 TTL 等于 0 - 如果原始数据包已分段,并且在片段重组期间 TTL 达到 0,则发送此代码。该代码只能从目标主机发送。
Code 1 - TTL equals 0 during reassembly - This is sent if the original packet was fragmented, and TTL reached 0 during reassembly of the fragments. This code should only be sent from the destination host.
参数问题 ICMP 使用类型 12,并且它也使用 2 个代码。参数问题消息用于告诉发送主机网关或接收主机在理解部分 IP 标头(例如错误)时遇到问题,或者缺少某些必需的选项。
The parameter problem ICMP uses type 12 and it has 2 codes that it uses as well. Parameter problem messages are used to tell the sending host that the gateway or receiving host had problems understanding parts of the IP headers such as errors, or that some required options where missing.
参数问题类型包含一个特殊的标头,它是一个指向原始数据包中导致错误的字段的指针(如果代码为 0)。可以使用以下代码:
The parameter problem type contains one special header, which is a pointer to the field that caused the error in the original packet, if the code is 0 that is. The following codes are available:
代码 0 - IP 标头错误(包罗万象的错误) - 这是如上所述的包罗万象的错误消息。该代码与指针一起用于指出 IP 标头的哪一部分包含错误。
Code 0 - IP header bad (catchall error) - This is a catchall error message as discussed just above. Together with the pointer, this code is used to point to which part of the IP header contained an error.
代码 1 - 缺少必需的选项 - 如果缺少所需的 IP 选项,则使用此代码来说明这一情况。
Code 1 - Required options missing - If an IP option that is required is missing, this code is used to tell about it.
时间戳类型现在已经过时了,但我们在这里简单介绍一下。回复和请求都有一个代码 (0)。请求的类型为 13,而回复的类型为 14。时间戳数据包包含 3 个 32 位时间戳,计算自午夜 UT(通用时间)以来的毫秒数。
The timestamp type is obsolete these days, but we bring it up briefly here. Both the reply and the request has a single code (0). The request is type 13 while the reply is type 14. The timestamp packets contains 3 32-bit timestamps counting the milliseconds since midnight UT (Universal Time).
第一个时间戳是起源时间戳,其中包含发送者上次接触数据包的时间。接收时间戳是回显主机第一次接触数据包的时间,传输时间戳是发送数据包之前设置的最后一个时间戳。
The first timestamp is the Originate timestamp, which contains the last time the sender touched the packet. The receive timestamp is the time that the echoing host first touched the packet and the transmit timestamp is the last timestamp set just previous to sending the packet.
每个时间戳消息还包含与 ICMP 回显数据包相同的标识符和序列号。
Each timestamp message also contains the same identifiers and sequence numbers as the ICMP echo packets.
信息请求和回复类型已过时,因为 IP 协议之上的协议现在可以在必要时处理此问题(DHCP 等)。信息请求会从我们所连接的网络上的任何应答主机生成答复。
The information request and reply types are obsolete since there are protocols on top of the IP protocol that can now take care of this when necessary (DHCP, etc). The information request generates a reply from any answering host on the network that we are attached to.
希望接收信息的主机创建一个数据包,其中源地址设置为我们所连接的网络(例如 192.168.0.0),目标网络设置为 0。回复将包含有关我们的号码的信息(网络掩码和IP地址)。
The host that wishes to receive information creates a packet with the source address set to the network we are attached to (for example, 192.168.0.0), and the destination network set to 0. The reply will contain information about our numbers (netmask and ip address).
信息请求通过 ICMP 类型 15 运行,而回复则通过类型 16 发送。
The information request is run through ICMP type 15 while the reply is sent via type 16.
流控制传输协议 (SCTP) 是游戏中相对较新的协议,但由于它的使用量不断增长并且补充了 TCP 和 UDP 协议,因此我选择添加有关它的这一部分。它具有比 TCP 更高的可靠性,同时协议头的开销更低。
Stream Control Transmission Protocol (SCTP) is a relatively new protocol in the game, but since it is growing in usage and complements the TCP and UDP protocols, I have chosen to add this section about it. It has an even higher reliability than TCP, and at the same time a lower overhead from protocol headers.
SCTP 有一些非常有趣的功能。对于那些希望了解更多信息的人,请阅读 RFC 3286 - 流控制传输协议简介和RFC 2960 - 流控制传输协议文档。第一篇文档是 SCTP 的介绍,对于那些仍然需要更多信息的人来说应该非常有趣。第二个文档是协议的实际规范,除非您正在为协议进行开发或真的感兴趣,否则它可能不太有趣。
SCTP has a couple of very interesting features that can be interesting. For those who wish to learn more about this, read the RFC 3286 - An Introduction to the Stream Control Transmission Protocol and RFC 2960 - Stream Control Transmission Protocol document. The first document is an introduction to SCTP and should be very interesting to people who are still in need of more information. The second document is the actual specification for the protocol, which might be less interesting unless you are developing for the protocol or are really interested.
该协议最初是为 IP 电话或 IP 语音 (VoIP) 开发的,因此具有一些非常有趣的属性。工业级 VoIP 需要非常高的可靠性,这意味着必须在系统中内置大量弹性来处理不同类型的问题。以下列出了 SCTP 的基本功能。
The protocol was originally developed for Telephony over IP, or Voice over IP (VoIP), and has some very interesting attributes due to this. Industry grade VoIP requires very high reliability for one, and this means that a lot of resilience has to be built into the system to handle different kind of problems. The following is a list of the basic features of SCTP.
具有多播属性的单播。这意味着它是一种点对点协议,但能够在同一终端主机上使用多个地址。换句话说,它可以使用不同的路径到达最终主机。相比之下,如果传输路径中断,TCP 就会中断,除非 IP 协议对其进行纠正。
Unicast with Multicast properties. This means it is a point-to-point protocol but with the ability to use several addresses at the same end host. It can in other words use different paths to reach the end host. TCP in comparison breaks if the transport path breaks, unless the IP protocol corrects it.
可靠的传输。它使用校验和和 SACK 来检测损坏、损坏、丢弃、重复和重新排序的数据。然后它可以根据需要重新传输数据。这与 TCP 几乎相同,但 SCTP 在重新排序数据时更具弹性,并且允许更快的拾取。
Reliable transmission. It uses checksums and SACK to detect corrupted, damaged, discarded, duplicated and reordered data. It can then retransmit data as necessary. This is pretty much the same as TCP, but SCTP is more resilient when it comes to reordered data and allows for faster pickups.
消息导向。每条消息都可以被构建,因此您可以密切关注数据流的结构和顺序。TCP是面向字节的,你得到的只是字节流,内部不同数据之间没有任何顺序。换句话说,您需要 TCP 中的额外抽象层。
Message oriented. Each message can be framed and hence you can keep tabs on the structure and order of the datastream. TCP is byte oriented and all you get is a stream of bytes without any order between different data inside. You need an extra layer of abstraction in TCP in other words.
速率自适应。它的开发是为了与 TCP 进行带宽合作并共存。它与 TCP 一样根据网络负载条件进行扩展和缩减。它还具有相同的算法,可以在数据包丢失时缓慢启动。还支持 ECN。
Rate adaptive. It is developed to cooperate and co-exist with TCP for bandwidth. It scales up and down based on network load conditions just the same as TCP. It also has the same algorithms for slow starting when packets where lost. ECN is also supported.
多归属。如前所述,它能够直接在协议中设置不同的终端节点,因此不必依赖 IP 层来实现弹性。
Multi-homing. As previously mentioned, it is able to set up different end nodes directly in the protocol, and hence doesn't have to rely on the IP layer for resilience.
多流。这允许同一流内同时存在多个流。因此得名流控制传输协议。例如,可以打开单个流来下载单个网页,然后可以在同一流中同时下载所有图像和 html 文档。或者为什么不使用数据库协议来创建单独的控制流,然后使用多个流同时接收不同查询的输出。
Multi-streaming. This allows for multiple simultaneous streams inside the same stream. Hence the name Stream Control Transmission Protocol. A single stream can for example be opened to download a single webpage, and all the images and html documents can then be downloaded within the same stream simultaneously. Or why not a database protocol which can create a separate control stream and then use several streams to receive the output from the different queries simultaneously.
引发。4 数据包发起连接,其中数据包 3 和 4 可用于发送数据。默认情况下会实现相当于 syncookie 的功能,以避免 DoS 攻击。INIT 冲突解决以避免多个同时发生的 SCTP 连接。
Initiation. 4 packet initiation of connections where packet 3 and 4 can be used to send data. The equivalent of syncookies is implemented by default to avoid DoS attacks. INIT collision resolution to avoid several simultaneous SCTP connections.
这个清单还可以更长,但我不会。大多数信息都是从RFC 3286 - 流控制传输协议简介 文档中收集的,因此请阅读该文档以获取更多信息。
This list could be made even longer, but I will not. Most of this information is gathered from the RFC 3286 - An Introduction to the Stream Control Transmission Protocol document, so read on there for more information.
在 SCTP 中,我们谈论的是块,而不是数据包或窗口。由于该协议是面向消息的,因此 SCTP 帧可以包含多个不同的块。块可以是控制块或数据块。控制块用于控制会话,数据块用于发送实际数据。 In SCTP we talk about chunks, not packets or windows anymore. An SCTP frame can contain several different chunks since the protocol is message oriented. A chunk can either be a control or a data chunk. Control chunks is used to control the session, and data chunks are used to send actual data. |
每个连接都是通过在想要相互通信的两个主机之间创建关联来初始化的。当用户需要时,该关联被初始化。稍后根据需要使用它。
Each connection is initialized by creating an association between the two hosts that wants to talk to each other. This association is initialized when a user needs it. It is later used as needed.
初始化是通过4个数据包完成的。首先发送一个 INIT 块,并用包含 cookie 的 INIT ACK 进行回复,此后连接可以开始发送数据。然而,在初始化过程中又发送了两个数据包。cookie 使用 COOKIE ECHO 块进行回复,最后使用 COOKIE ACK 块进行回复。
The initialization is done through 4 packets. First an INIT chunk is sent, which is replied to with an INIT ACK containing a cookie, after this the connection can start sending data. However, two more packets are sent in the initialization. The cookie is replied to with a COOKIE ECHO chunk, which is finally replied to with a COOKIE ACK chunk.
此时SCTP就可以发送数据了。如前所述,在 SCTP 中存在控制块和数据块。数据块使用DATA块来发送,并且DATA块通过发送SACK块来确认。这实际上与 TCP SACK 相同。SACK 块是控制块。
SCTP can at this point send data. In SCTP there are control chunks and data chunks, as previously stated. Data chunks are sent using DATA chunks, and DATA chunks are acknowledged by sending a SACK chunk. This works practically the same as a TCP SACK. SACK chunks are control chunks.
除此之外,还可以看到一些其他控制块。其中一个为 HEARTBEAT 和 HEARTBEAT ACK 块,另一个为 ERROR 块。HEARTBEAT 用于保持连接处于活动状态,ERROR 用于通知连接中的不同问题或错误,例如无效的流 ID 或缺少强制参数等。
On top of this, there are some other control chunks that can be seen. HEARTBEAT and HEARTBEAT ACK chunks for one, and ERROR chunks for another. HEARTBEATs are used to keep the connection alive, and ERROR is used to inform of different problems or errors in the connection, such as invalid stream id's or missing mandatory parameters et cetera.
SCTP 连接最终通过 ABORT 块或正常 SHUTDOWN 块关闭。SCTP不像TCP那样具有半关闭状态,换句话说,一端不能继续发送数据,而另一端已经关闭了发送套接字。
The SCTP connection is finally closed by either an ABORT chunk or by a graceful SHUTDOWN chunk. SCTP doesn't have a half-closed state as TCP, in other words one side can not continue sending data while the other end has closed its sending socket.
当用户/应用程序想要正常关闭 SCTP 套接字时,它会告诉协议 SHUTDOWN。然后,SCTP 发送仍在其缓冲区中的所有数据,然后发送 SHUTDOWN 块。当另一端收到SHUTDOWN后,将停止接受应用程序的数据并发送完所有数据。一旦它获得了数据的所有 SACK,它将发送一个 SHUTDOWN ACK 块,一旦关闭方收到该块,它最终将回复一个 SHUTDOWN COMPLETE 块。整个会议现已结束。
When the user/application wants to close the SCTP socket gracefully, it tells the protocol to SHUTDOWN. SCTP then sends all the data still in its buffers, and then sends a SHUTDOWN chunk. When the other end receives the SHUTDOWN, it will stop accepting data from the application and finish sending all the data. Once it has gotten all the SACK's for the data, it will send a SHUTDOWN ACK chunk and once the closing side has received this chunk, it will finally reply with a SHUTDOWN COMPLETE chunk. The whole session is now closed.
关闭会话的另一种方法是 ABORT 它。这是删除 SCTP 关联的一种不礼貌的方式。当连接方想要立即删除 SCTP 关联时,它会发送带有所有已签名的正确值的 ABORT 块。缓冲区等中的所有数据将被丢弃,然后关联将被删除。接收端在验证ABORT chunk后也会做同样的事情。
Another way of closing a session is to ABORT it. This is an ungraceful way of removing an SCTP association. When a connecting party wants to remove an SCTP association instantaneously, it sends an ABORT chunk with all the right values signed. All data in the buffers et cetera will be discarded and the association will then be removed. The receiving end will do the same after verifying the ABORT chunk.
这将是对 SCTP 标头的非常简短的介绍。SCTP 有许多不同类型的数据包,因此我将尝试尽可能遵循 RFC 以及它们如何描述不同的标头,首先对适用于所有 SCTP 数据包的标头进行一般概述。
This will be a very brief introduction to the SCTP headers. SCTP has a lot of different types of packets, and hence I will try to follow the RFC's as close as possible and how they depict the different headers, starting with a general overview of the headers applicable to all SCTP packets.
这是 SCTP 数据包如何布局的一般概述。基本上,您首先有一个公共标头,其中包含描述整个数据包以及源端口和目标端口等的信息。有关公共标头的信息,请参阅下面的更多信息。
This is a generic overview of how a SCTP packet is laid out. Basically, you have a common header first with information describing the whole packet, and the source and destination ports etc. See more below for information on the common header.
在公共标头之后,发送可变数量的块,最多达到 MTU 中可能的最大数量。除了 INIT、INIT ACK 和 SHUTDOWN COMPLETE 不得捆绑之外,所有块都可以捆绑。数据块可以被分解以适合数据包的 MTU。
After the common header a variable number of chunks are sent, up to the maximum possible in the MTU. All chunks can be bundled except for INIT, INIT ACK and SHUTDOWN COMPLETE, which must not be bundled. DATA chunks may be broken down to fit inside the MTU of the packets.
每个 SCTP 数据包都包含通用标头,如上所示。标头包含四个不同的字段,并为每个 SCTP 数据包设置。
Every SCTP packet contains the Common header as seen above. The header contains four different fields and is set for every SCTP packet.
源端口 - 位 0-15。该字段给出数据包的源端口,即从哪个端口发送的。与 TCP 和 UDP 源端口相同。
Source port - bit 0-15. This field gives the source port of the packet, which port it was sent from. The same as for TCP and UDP source port.
目标端口 - 位 16-31。这是数据包的目标端口,即数据包要去的端口。它与 TCP 和 UDP 目标端口相同。
Destination port - bit 16-31. This is the destination port of the packet, ie., the port that the packet is going to. It is the same as for the TCP and UDP destination port.
验证标签 - 位 32-63。验证标签用于验证数据包来自正确的发送者。它始终设置为与关联初始化期间发起标记中的其他对等方收到的值相同的值,但有一些例外:
Verification Tag - bit 32-63. The verification tag is used to verify that the packet comes from the correct sender. It is always set to the same value as the value received by the other peer in the Initiate Tag during the association initialization, with a few exceptions:
包含 INIT 块的 SCTP 数据包必须将验证标记设置为 0。
An SCTP packet containing an INIT chunk must have the Verification tag set to 0.
设置了 T 位的 SHUTDOWN COMPLETE 块必须具有从 SHUTDOWN-ACK 块的验证标记复制的验证标记。
A SHUTDOWN COMPLETE chunk with the T-bit set must have the verification tag copied from the verification tag of the SHUTDOWN-ACK chunk.
包含 ABORT 块的数据包可以将验证标签设置为与导致 ABORT 的数据包相同的验证标签。
Packets containing ABORT chunk may have the verification tag set to the same verification tag as the packet causing the ABORT.
校验和 - 位 64-95。基于Adler-32算法对整个SCTP数据包计算的校验和。有关此算法的更多信息, 请阅读RFC 2960 - 流控制传输协议,附录 B。
Checksum - bit 64-95. A checksum calculated for the whole SCTP packet based on the Adler-32 algorithm. Read RFC 2960 - Stream Control Transmission Protocol, appendix B for more information about this algorithm.
所有 SCTP 块都遵循特殊的布局,如上所示。这不是一个实际的标题,而是它们外观的形式化方式。
All SCTP chunks has a special layout that they all adhere to as can be seen above. This isn't an actual header, but rather a formalized way of how they do look.
类型 - 位 0-7。该字段指定数据包的块类型,例如它是 INIT 还是 SHUTDOWN 块还是什么?每个块类型都有一个特定的编号,并在下图中指定。以下是块类型的完整列表:
Type - bit 0-7. This field specifies the chunk type of the packet, for example is it an INIT or SHUTDOWN chunk or what? Each chunk type has a specific number, and is specified in the image below. Here is a complete list of Chunk types:
表 2-1。SCTP 类型
Table 2-1. SCTP Types
| 块数 | 块名称 |
|---|---|
| 0 | 有效负载数据(DATA) |
| 1 | 启动(INIT) |
| 2 | 启动确认(INIT ACK) |
| 3 | 选择性确认 (SACK) |
| 4 | 心跳请求(HEARTBEAT) |
| 5 | 心跳确认(HEARTBEAT ACK) |
| 6 | 中止(中止) |
| 7 | 关机(SHUTDOWN) |
| 8 | 关机确认(SHUTDOWN ACK) |
| 9 | 操作错误(ERROR) |
| 10 | 状态 Cookie (COOKIE ECHO) |
| 11 | Cookie 确认(COOKIE ACK) |
| 12 | 保留用于显式拥塞通知回显 (ECNE) |
| 13 | 保留用于减少拥塞窗口 (CWR) |
| 14 | 关机完成(SHUTDOWN COMPLETE) |
| 15-62 | 为 IETF 保留 |
| 63 | IETF 定义的块扩展 |
| 64-126 | 保留给 IETF |
| 127 | IETF 定义的块扩展 |
| 128-190 | 保留给 IETF |
| 191 | IETF 定义的块扩展 |
| 192-254 | 保留给 IETF |
| 255 | IETF 定义的块扩展 |
块标志 - 位 8-15。块标志通常不被使用,但如果没有其他情况,则设置为将来使用。它们是其他对等点可能需要的块特定标志或信息位。根据规范,此时标志仅在 DATA、ABORT 和 SHUTDOWN COMPLETE 数据包中使用。然而,这可能会改变。
Chunk Flags - bit 8-15. The chunk flags are generally not used but are set up for future usage if nothing else. They are chunk specific flags or bits of information that might be needed for the other peer. According to specifications, flags are only used in DATA, ABORT and SHUTDOWN COMPLETE packets at this moment. This may change however.
很多时候,当您阅读 RFC 时,您可能会遇到一些已被证实的老问题。RFC 2960 - 流控制传输协议文档就是其中一个示例,其中特别指定块标志应始终设置为 0 并被忽略,除非用于某些用途。到处都是这样写的,这会为将来带来问题。如果您进行防火墙或路由,请非常小心,因为此类字段的规范将来可能会发生变化,从而在没有任何合法原因的情况下破坏您的防火墙。例如,以前在 IP 标头中实施 ECN 时就发生过这种情况。更多内容请参见本章的 IP 标头部分。 A lot of times when you read an RFC, you might run into some old proven problems. The RFC 2960 - Stream Control Transmission Protocol document is one example of this, where they specifically specify that the Chunk flags should always be set to 0 and ignored unless used for something. This is written all over the place, and it begs for problems in the future. If you do firewalling or routing, watch out very carefully for this, since specifications for fields like this may change in the future and hence break at your firewall without any legit reason. This happened before with the implementation of ECN in the IP headers for example. See more in the IP headers section of this chapter. |
块长度 - 位 16-31。这是以字节计算的块长度。它包括所有标头,包括块类型、块标志、块长度和块值。如果没有 chunk 值,则 chunk 长度将设置为 4(字节)。
Chunk Length - bit 16-31. This is the chunk length calculated in bytes. It includes all headers, including the chunk type, chunk flags, chunk length and chunk value. If there is no chunk value, the chunk length will be set to 4 (bytes).
块值 - 位 32-n。这是特定于每个块的,并且可能包含更多与块类型相关的标志和数据。有时它可能为空,在这种情况下块长度将设置为 4。
Chunk Value - bit 32-n. This is specific to each chunk and may contain more flags and data pertaining to the chunk type. Sometimes it might be empty, in which case the chunk length will be set to 4.
ABORT 块用于中止关联,如本章前面的关闭和中止部分所述。ABORT 在关联中出现不可恢复的错误(例如错误的标头或数据)时发出。
The ABORT chunk is used to abort an association as previously described in the Shutdown and abort section of this chapter. ABORT is issued upon unrecoverable errors in the association such as bad headers or data.
类型 - 位 0-7。对于该块类型,始终设置为 6。
Type - bit 0-7. Always set to 6 for this chunk type.
保留 - 位 8-14。为未来的块标志保留,但在撰写本文时尚未使用。有关块标志字段的更多信息, 请参阅SCTP 公共和通用标头。
Reserved - bit 8-14. Reserved for future chunk flags but not used as of writing this. See the SCTP Common and generic headers for more information about the chunk flags field.
T 位 - 位 15。如果该位设置为 0,则发送方拥有与其已销毁的该数据包关联的 TCB。如果发送方没有 TCB,则 T 位应设置为 1。
T-bit - bit 15. If this bit is set to 0, the sender had a TCB associated with this packet that it has destroyed. If the sender had no TCB the T-bit should be set to 1.
长度 - 位 16-31。设置块的长度(以字节为单位),包括错误原因。
Length - bit 16-31. Sets the length of the chunk in bytes including error causes.
COOKIE ACK 块在连接初始化期间使用,而不会在连接的其他任何地方使用。它必须位于所有 DATA 和 SACK 块之前,但可以与这些数据包中的第一个数据包在同一数据包中发送。
The COOKIE ACK chunk is used during the initialization of the connection and never anywhere else in the connection. It must precede all DATA and SACK chunks but may be sent in the same packet as the first of these packets.
类型 - 位 0-7。对于此类型,始终设置为 11。
Type - bit 0-7. Always set to 11 for this type.
块标志 - 位 8-15。到目前为止还没有使用过。根据 RFC 2960 - 流控制传输协议,应始终设置为 0 。您应该始终留意 RFC 中规定的这种特定行为,因为它将来可能会发生变化,从而破坏您的防火墙等。就像 IP 和 ECN 发生的情况一样。有关详细信息,请参阅SCTP 通用和通用标头 部分。
Chunk flags - bit 8-15. Not used so far. Should always be set to 0 according to RFC 2960 - Stream Control Transmission Protocol. You should always watch out for this kind of specific behaviour stated by RFC's since it might change in the future, and hence break your firewalls etc. Just the same as happened with IP and ECN. See the SCTP Common and generic headers section for more information.
长度 - 位 16-31。该块应始终为 4(字节)。
Length - bit 16-31. Should always be 4 (bytes) for this chunk.
COOKIE ECHO 块在 SCTP 连接初始化期间由发起方用于回复响应方在 INIT ACK 数据包中的 State cookie 字段中发送的 cookie。它可以与同一数据包中的 DATA 块一起发送,但在这种情况下必须先于 DATA 块。
The COOKIE ECHO chunk is used during the initialization of the SCTP connection by the initiating party to reply to the cookie sent by the responding party in the State cookie field in the INIT ACK packet. It may be sent together with DATA chunks in the same packet, but must precede the DATA chunks in such case.
类型 - 位 0-7。该块的块类型始终设置为 10。
Type - bit 0-7. The chunk type is always set to 10 for this chunk.
块标志 - 位 8-15。该字段目前尚未使用。RFC 指定标志应始终设置为 0,但这可能会导致问题,如上面的SCTP 公共和通用标头部分所示,特别是块标志说明。
Chunk flags - bit 8-15. This field is not used today. The RFC specifies that the flags should always be set to 0, but this might cause trouble as can be seen in the SCTP Common and generic headers section above, specifically the Chunk flags explanation.
长度 - 位 16-31。指定块的长度,包括类型、块标志、长度和 cookie 字段(以字节为单位)。
Length - bit 16-31. Specifies the length of the chunk, including type, chunk flags, length and cookie fields in bytes.
Cookie - 位 32-n。该字段包含在前一个 INIT ACK 块中发送的 cookie。它必须与响应方发送的cookie完全相同,另一端才能真正打开连接。RFC 2960 - 流控制传输协议 规定cookie应该尽可能小以确保互操作性,这是非常模糊的并且没有说太多。
Cookie - bit 32-n. This field contains the cookie as sent in the previous INIT ACK chunk. It must be the exact same as the cookie sent by the responding party for the other end to actually open the connection. The RFC 2960 - Stream Control Transmission Protocol specifies that the cookie should be as small as possible to insure interoperability, which is very vague and doesn't say much.
DATA 块用于通过流发送实际数据,并且在某些方面具有相当复杂的标头,但总体上并不比 TCP 标头差。每个数据块可能是不同流的一部分,因为每个 SCTP 连接可以处理多个不同的流。
DATA chunks are used to send actual data through the stream and have rather complex headers in some ways, but not really worse than TCP headers in general. Each DATA chunk may be part of a different stream, since each SCTP connection can handle several different streams.
类型 - 位 0-7。对于数据块,类型字段应始终设置为 0。
Type - bit 0-7. The Type field should always be set to 0 for DATA chunks.
保留 - 位 8-12。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Reserved - bit 8-12. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
U 位 - 位 13。U 位用于指示这是否是无序数据块。如果是,则接收主机必须忽略流序列号并将其立即发送到上层或尝试重新排序数据块。
U-bit - bit 13. The U-bit is used to indicate if this is an unordered DATA chunk. If it is, the Stream Sequence Number must be ignored by the receiving host and send it on to the upper layer without delay or tries to re-order the DATA chunks.
B 位 - 位 14。B 位用于指示分段数据块的开始。如果该位被设置并且E(结束)位未被设置,则表明这是已被分割成多个DATA块的块的第一个片段。
B-bit - bit 14. The B-bit is used to indicate the beginning of a fragmented DATA chunk. If this bit is set and the E (ending) bit is not set, it indicates that this is the first fragment of a chunk that has been fragmented into several DATA chunks.
E 位 - 位 15。E 位用于指示分段数据块的结束。如果在块上设置此标志,它会向 SCTP 接收器发出信号,表明它可以开始重新组装片段并将它们传递到上层。如果数据包的两个 BE 位都设置为 0,则表示该块是分段块的中间部分。如果两个 BE 位都设置为 1,则表示数据包未分段并且不需要重组等。
E-bit - bit 15. The E-bit is used to indicate the ending of a fragmented DATA chunk. If this flag is set on a chunk, it signals to the SCTP receiver that it can start reassembling the fragments and pass them on to the upper layer. If a packet has both the BE-bits set to set to 0, it signals that the chunk is a middle part of a fragmented chunk. If both BE-bits are set to 1 it signals that the packet is unfragmented and requires no reassembly et cetera.
长度 - 位 16-31。整个 DATA 块的长度(以字节为单位计算),包括块类型字段,一直到块末尾。
Length - bit 16-31. The length of the whole DATA chunk calculated in bytes,including the chunk type field and on until the end of the chunk.
TSN - 位 32-63。传输序列号 (TSN) 在 DATA 块中发送,接收主机使用 TSN 通过回复 SACK 块来确认该块已正确通过。这是整个 SCTP 协会的总体价值。
TSN - bit 32-63. The Transmission Sequence Number (TSN) is sent in the DATA chunk, and the receiving host uses the TSN to acknowledge that the chunk got through properly by replying with a SACK chunk. This is an overall value for the whole SCTP association.
流标识符 - 位 64-79。流标识符与数据块一起发送,以识别数据块与哪个流关联。之所以使用它,是因为 SCTP 可以在单个关联内传输多个流。
Stream Identifier - bit 64-79. The Stream Identifier is sent along with the DATA chunk to identify which stream the DATA chunk is associated with. This is used since SCTP can transport several streams within a single association.
流序列号 - 位 80-95。这是由流标识符标识的特定流的块的序列号。该序列号对于每个流标识符是特定的。如果一个块已被分段,则原始块的所有片段的流序列号必须相同。
Stream Sequence Number - bit 80-95. This is the sequence number of the chunk for the specific stream identified by the Stream Identifier. This sequence number is specific for each stream identifier. If a chunk has been fragmented, the Stream Sequence Number must be the same for all fragments of the original chunk.
有效负载协议标识符 - 位 96-127。该值由上层或使用 SCTP 协议的应用程序填充,作为相互识别 DATA 块内容的方式。该字段必须始终发送,包括分段发送,因为路由器和防火墙等可能需要该信息。如果该值设置为0,则该值不是由上层设置的。
Payload Protocol Identifier - bit 96-127. This value is filled in by the upper layers, or applications using the SCTP protocol as a way to identify to each other the content of the DATA chunk. The field must always be sent, including in fragments since routers and firewalls, et cetera, on the way might need the information. If the value was set to 0, the value was not set by the upper layers.
用户数据 - 位 128-n。这是块正在传输的实际数据。它的长度可以是可变的,以偶数八位字节结尾。它是由流S中的流序列号n指定的流中的数据。
User data - bit 128-n. This is the actual data that the chunk is transporting. It can be of variable length, ending on an even octet. It is the data in the stream as specified by the stream sequence number n in the stream S.
发送 ERROR 块是为了通知其他对等方当前流中的任何问题。每个错误块可以包含一个或多个错误原因,这些错误原因在RFC 2960 - 流控制传输协议文档中进行了更具体的详细说明。除了基本的 ERROR 块之外,我不会在这里讨论更多细节,因为它会包含太多信息。ERROR 块本身并不是致命的,而是详细说明了已发生的错误。然而,它可以与 ABORT 块一起使用,以在终止连接之前通知对等方错误。
The ERROR chunk is sent to inform the other peer of any problems within the current stream. Each ERROR chunk can contain one or more Error Causes, which are more specifically detailed in the RFC 2960 - Stream Control Transmission Protocol document. I will not go into further details here than the basic ERROR chunk, since it would be too much information. The ERROR chunk is not fatal in and of itself, but rather details an error that has happened. It may however be used together with an ABORT chunk to inform the peer of the error before killing the connection.
类型 - 位 0-7。对于 ERROR 块,该值始终设置为 9。
Type - bit 0-7. This value is always set to 9 for ERROR chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
长度 - 位 16-31。指定块的长度(以字节为单位),包括所有错误原因。
Length - bit 16-31. Specifies the length of the chunk in bytes, including all the Error Causes.
错误原因 - 位 32-n。每个错误块可能包含一个或多个错误原因,它通知对方连接出现问题。每个错误原因都遵循特定的格式,如RFC 2960 - 流控制传输协议文档中所述。我们在这里不会详细讨论它们,只是说它们都包含原因代码、原因长度和原因特定信息字段。可能的错误原因如下:
Error causes - bit 32-n. Each ERROR chunk may contain one or more Error Causes, which notifies the opposite peer of a problem with the connection. Each Error Cause follows a specific format, as described in the RFC 2960 - Stream Control Transmission Protocol document. We will not go into them here more than to say that they all contain an Cause Code, cause length and cause specific information field. The following Error Causes are possible:
HEARTBEAT 块由对等方之一发送,用于探测并查明特定 SCTP 端点地址是否已启动。这被发送到在关联初始化期间协商的不同地址,以查明它们是否全部启动。
The HEARTBEAT chunk is sent by one of the peers to probe and find out if a specific SCTP endpoint address is up. This is sent to the different addresses that was negotiated during the initialization of the association to find out if they are all up.
类型 - 位 0-7。对于 HEARTBEAT 块,类型始终设置为 4。
Type - bit 0-7. The type is always set to 4 for HEARTBEAT chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
长度 - 位 16-31。整个块的长度,包括心跳信息 TLV。
Length - bit 16-31. The length of the whole chunk, including the Heartbeat Information TLV.
心跳信息 TLV - 位 32-n。这是RFC 2960 - 流控制传输协议文档中定义的可变长度参数。这是 HEARTBEAT 块的强制参数,包含 3 个字段:信息类型 = 1、信息长度和发送者特定的心跳信息参数。最后一个字段应该是某种发送者特定的信息字段,例如发送心跳时的时间戳和目标 IP 地址。然后,该信息会在 HEARTBEAT ACK 块中返回。
Heartbeat Information TLV - bit 32-n. This is a variable-length parameter as defined inside the RFC 2960 - Stream Control Transmission Protocol document. This is a mandatory parameter for the HEARTBEAT chunks that contains 3 fields, info type = 1, info length and a sender-specific Heartbeat Information parameter. The last field should be a sender-specific information field of some kind, for example a timestamp when the heartbeat was sent and a destination IP address. This is then returned in the HEARTBEAT ACK chunk.
HEARTBEAT ACK 用于确认已收到 HEARTBEAT 并且连接工作正常。该块始终发送到与发送请求的 IP 地址相同的 IP 地址。
The HEARTBEAT ACK is used to acknowledge that a HEARTBEAT was received and that the connection is working properly. The chunk is always sent to the same IP address as the request was sent from.
类型 - 位 0-7。HEARTBEAT ACK 块始终设置为 5。
Type - bit 0-7. Always set to 5 for HEARTBEAT ACK chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。HEARTBEAT ACK 块的长度(包括心跳信息 TLV),以字节为单位计算。
Chunk length - bit 16-31. The length of the HEARTBEAT ACK chunk including the Heartbeat Information TLV, calculated in bytes.
心跳信息 TLV - 位 32-n。该字段必须包含在原始 HEARTBEAT 块中发送的心跳信息参数。
Heartbeat Information TLV - bit 32-n. This field must contain the Heartbeat Information parameter that was sent in the original HEARTBEAT chunk.
INIT 块用于启动与目标主机的新关联,并且是连接主机发送的第一个块。INIT 块包含几个强制的固定长度参数和一些可选的可变长度参数。固定长度强制参数已经在上述标头中,并且是初始标签、通告接收器窗口信用、出站流数量、入站流数量和初始TSN参数。之后是几个可选参数,它们将与下面的可选参数段落一起列出。
The INIT chunk is used to initiate a new association with a destination host, and is the first chunk to be sent by the connecting host. The INIT chunk contains several mandatory fixed length parameters, and some optional variable length parameters. The fixed length mandatory parameters are already in the above headers, and are the Initiate Tag, Advertised Receiver Window Credit, Number of Outbound Streams, Number of Inbound Streams and the Initial TSN parameters. After this comes a couple of optional parameters, they will be listed with the optional parameters paragraph below.
类型 - 位 0-7。对于 INIT 块,类型字段始终设置为 1。
Type - bit 0-7. The type field is always set to 1 for INIT chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。块长度是整个数据包的长度,包括标头中的所有内容,包括可选参数。
Chunk Length - bit 16-31. The chunk length is the length of the whole packet, including everything in the headers, including the optional parameters.
起始标签 - 位 32-63。启动标签在 INIT 块内设置,并且接收器必须使用它来确认此后在已建立关联的验证标签内的所有数据包。启动标签可以采用除 0 之外的任何值。如果该值无论如何都是 0,则接收器必须以 ABORT 做出反应。
Initiate Tag - bit 32-63. The Initiate Tag is set within the INIT chunk and must be used by the receiver to acknowledge all packets henceforth, within the Verification Tag of the established association. The Initiate Tag may take any value except 0. If the value is 0 anyways, the receiver must react with an ABORT.
通告的接收器窗口信用 (a_rwnd) - 位 64-95。这是 INIT 块的发送方将为该关联分配的最小接收缓冲区(以字节为单位)。然后,a_rwnd 的接收方可以使用它来了解它可以发送多少数据而不被 SACK'ed。该窗口不应减小,但可以通过在 SACK 块中发送新的 a_rwnd 来减小。
Advertised Receiver Window Credit (a_rwnd)- bit 64-95. This is the minimum receiving buffer that the sender of the INIT chunk will allocate for this association, in bytes. This can then be used by the receiver of the a_rwnd, to know how much data it can send out without being SACK'ed. This window should not be lessened, but it might by sending the new a_rwnd in a SACK chunk.
出站流的数量 - 位 96-111。这指定连接主机希望创建到接收主机的出站流的最大数量。该值不能为 0,如果是,接收主机应立即中止关联。没有协商出站或入站流的最小数量,它只是设置为任一主机在标头中设置的最低数量。
Number of Outbound Streams - bit 96-111. This specifies the maximum number of outbound streams that the connecting host wishes to create to the receiving host. The value must not be 0, and if it is, the receiving host should ABORT the association immediately. There is no negotiation of the minimum number of outbound or inbound streams, it is simply set to the lowest that either host has set in the header.
入站流的数量 - 位 112-127。指定发送对等方允许接收主机在此关联中创建的入站连接的最大数量。不得将其设置为 0,否则接收主机应中止连接。没有协商出站或入站流的最小数量,它只是设置为任一主机在标头中设置的最低数量。
Number of Inbound Streams - bit 112-127. Specifies the maximum number of inbound connections that the sending peer will allow the receiving host to create in this association. This must not be set to 0, or the receiving host should ABORT the connection. There is no negotiation of the minimum number of outbound or inbound streams, it is simply set to the lowest that either host has set in the header.
初始 TSN - 位 128-159。该值设置发送方在发送数据时将使用的初始传输序列号 (TSN)。该字段可以设置为与启动标签相同的值。
Initial TSN - bit 128-159. This value sets the initial Transmit Sequence Number (TSN) that the sender will use when sending data. The field may be set to the same value as the Initiate Tag.
除了上述强制固定长度标头之外,还可以设置一些可选的可变长度参数,并且必须设置至少 IPv4、IPv6 或主机名参数之一。只能设置一个主机名,如果设置了主机名,则不能设置 IPv4 或 IPv6 参数。还可以在同一个 INIT 块中设置多个 IPv4 和 IPv6 参数。此外,如果发送方只有一个可以到达的地址(该块应该来自该地址),则无需设置这些参数。这些参数用于设置哪些地址可用于连接到关联的另一端。这是 INIT 块中所有可用参数的完整列表:
On top of the above mandatory fixed length headers, there are also some optional variable length parameters that might be set, and at least one of the IPv4, IPv6 or Hostname parameters must be set. Only one Hostname may be set, and if a Hostname is set, no IPv4 or IPv6 parameters may be set. Multiple IPv4 and IPv6 parameters may also be set in the same INIT chunk. Also, none of these parameters needs to be set in case the sender only has one address that can be reached, which is where the chunk should be coming from. These parameters are used to set up which addresses may be used to connect to the other end of the association. This is a full list of all the parameters available in the INIT chunk:
表 2-3。INIT 变量参数
Table 2-3. INIT Variable Parameters
| 参数名称 | 地位 | 类型 值 |
|---|---|---|
| IPv4地址 | 选修的 | 5 |
| IPv6地址 | 选修的 | 6 |
| 饼干防腐剂 | 选修的 | 9 |
| 主机名地址 | 选修的 | 11 |
| 支持的地址类型 | 选修的 | 12 |
| 保留给支持 ECN 的 | 选修的 | 32768 |
下面我们描述 INIT 块中使用的三个最常见的参数。
Below we describe the three most common Parameters used in the INIT chunk.
IPv4 参数用于在 INIT 块中发送 IPv4 地址。IPv4 地址可用于通过关联发送数据。可以为单个 SCTP 关联指定多个 IPv4 和 IPv6 地址。
The IPv4 parameter is used to send an IPv4 address in the INIT chunk. The IPv4 address can be used to send data through the association. Multiple IPv4 and IPv6 addresses can be specified for a single SCTP association.
参数类型 - 位 0-15。对于 IPv4 地址参数,该值始终设置为 5。
Parameter Type - bit 0-15. This is always set to 5 for IPv4 address parameters.
长度 - 位 16-31。对于 IPv4 地址参数,该值始终设置为 8。
Length - bit 16-31. This is always set to 8 for IPv4 address parameters.
IPv4 地址 - 位 32-63。这是发送端点的 IPv4 地址。
IPv4 Address - bit 32-63. This is an IPv4 address of the sending endpoint.
该参数用于在 INIT 块中发送 IPv6 地址。然后可以使用该地址通过该关联联系发送端点。
This parameter is used to send IPv6 addresses in the INIT chunk. This address can then be used to contact the sending endpoint with this association.
类型 - 位 0-15。IPv6 参数始终设置为 6。
Type - bit 0-15. Always set to 6 for the IPv6 parameters.
长度位 16-31。IPv6 参数始终设置为 20。
Length bit 16-31. Always set to 20 for IPv6 parameters.
IPv6 地址 - 位 32-159。这是发送端点的 IPv6 地址,接收端点可使用该地址进行连接。
IPv6 address - bit 32-159. This is an IPv6 address of the sending endpoint that can be used to connect to by the receiving endpoint.
Hostname 参数用于将单个主机名作为地址发送。然后,Thea 接收主机必须查找主机名并使用从那里接收到的任何和/或所有地址。如果发送主机名参数,则不能发送其他 IPv4、IPv6 或主机名参数。
The Hostname parameter is used to send a single hostname as an address. Thea receiving host must then look up the hostname and use any and/or all of the addresses it receives from there. If a hostname parameter is sent, no other IPv4, IPv6 or Hostname parameters may be sent.
类型 - 位 0-15。主机名参数始终设置为 11。
Type - bit 0-15. This is always set to 11 for Hostname Parameters.
长度 - 位 16-31。整个参数的长度,包括类型、长度和主机名字段。主机名字段的长度可变。长度以字节为单位计算。
Length - bit 16-31. The length of the whole parameter, including type, length and hostname field. The Hostname field is variable length. The length is counted in bytes.
主机名 - 位 32-n。包含主机名的可变长度参数。主机名由接收端解析以获取可用于联系发送端点的地址。
Hostname - bit 32-n. A variable length parameter containing a hostname. The hostname is resolved by the receiving end to get the addresses that can be used to contact the sending endpoint.
INIT ACK 块是为了响应 INIT 块而发送的,并且包含基本相同的标头,但具有来自原始 INIT 块的接收者的值。此外,它还有两个额外的可变长度参数,State Cookie 和 Unrecognized Parameter 参数。
The INIT ACK chunk is sent in response to a INIT chunk and contains basically the same headers, but with values from the recipient of the original INIT chunk. In addition, it has two extra variable length parameters, the State Cookie and the Unrecognized Parameter parameters.
类型 - 位 0-7。对于 INIT ACK 块,此标头始终设置为 2。
Type - bit 0-7. This header is always set to 2 for INIT ACK chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。块长度是整个数据包的长度,包括标头中的所有内容以及可选参数。
Chunk Length - bit 16-31. The chunk length is the length of the whole packet, including everything in the headers, and the optional parameters.
起始标签 - 位 32-63。INIT ACK 块的初始标签的接收方必须保存该值并将其复制到发送给 INIT ACK 块的发送方的每个数据包的验证标签字段中。Initiate Tag 不能为 0,如果是,则 INIT ACK 块的接收方必须通过 ABORT 关闭连接。
Initiate Tag - bit 32-63. The receiver of the Initiate Tag of the INIT ACK chunk must save this value and copy it into the Verification Tag field of every packet that it sends to the sender of the INIT ACK chunk. The Initiate Tag must not be 0, and if it is, the receiver of the INIT ACK chunk must close the connection with an ABORT.
通告的接收器窗口信用 (a_rwnd) - 位 64-95。该块的发送者为流量找到的专用缓冲区,以字节为单位。专用缓冲区不应低于该值。
Advertised Receiver Window Credit (a_rwnd) - bit 64-95. The dedicated buffers that the sender of this chunk has located for traffic, counted in bytes. The dedicated buffers should never be lowered to below this value.
出站流的数量 - 位 96-111。发送主机希望创建多少个出站流。不能为 0,否则 INIT ACK 的接收方应中止关联。没有协商出站或入站流的最小数量,它只是设置为任一主机在标头中设置的最低数量。
Number of Outbound Streams - bit 96-111. How many outbound streams that the sending host wishes to create. Must not be 0, or the receiver of the INIT ACK should ABORT the association. There is no negotiation of the minimum number of outbound or inbound streams, it is simply set to the lowest that either host has set in the header.
入站流的数量 - 位 112-127。发送端点愿意接受多少个入站流。不能为 0,否则 INIT ACK 的接收方应中止关联。没有协商出站或入站流的最小数量,它只是设置为任一主机在标头中设置的最低数量。
Number of Inbound Streams - bit 112-127. How many inbound streams that the sending endpoint is willing to accept. Must not be 0, or the receiver of the INIT ACK should ABORT the association. There is no negotiation of the minimum number of outbound or inbound streams, it is simply set to the lowest that either host has set in the header.
初始 TSN - 位 128-159。这被设置为初始传输序列号(I-TSN),关联中的发送方将使用该序列号开始。
Initial TSN - bit 128-159. This is set to the Initial Transmission Sequence Number (I-TSN) which will be used by the sending party in the association to start with.
此后,INIT ACK 块继续使用可选的可变长度参数。除了添加了“状态 Cookie”和“无法识别的参数”参数以及删除了“支持的地址类型”参数之外,这些参数与 INIT 块完全相同。换句话说,该列表如下所示:
After this point, the INIT ACK chunk continues with optional variable-length parameters. The parameters are exactly the same as for the INIT chunk, with the exception of the addition of the State Cookie and the Unrecognized Parameters parameter, and the deletion of the Supported Address Types parameter. The list in other words look like this:
表 2-4。INIT ACK 可变参数
Table 2-4. INIT ACK Variable Parameters
| 参数名称 | 地位 | 类型 值 |
|---|---|---|
| IPv4地址 | 选修的 | 5 |
| IPv6地址 | 选修的 | 6 |
| 状态 Cookie | 强制的 | 7 |
| 无法识别的参数 | 选修的 | 8 |
| 饼干防腐剂 | 选修的 | 9 |
| 主机名地址 | 选修的 | 11 |
| 保留给支持 ECN 的 | 选修的 | 32768 |
State Cookie 在 INIT ACK 中用于向其他主机发送 cookie,并且在接收主机使用 COOKIE ECHO 块进行回复之前,无法保证关联。这与TCP协议中的SYN攻击基本相同。
The State Cookie is used in INIT ACK to send a cookie to the other host, and until the receiving host has replied with a COOKIE ECHO chunk, the association is not guaranteed. This is to prevent basically the same as a SYN attack in TCP protocol.
类型 - 位 0-15。所有状态 Cookie 参数始终设置为 7。
Type - bit 0-15. Always set to 7 for all State Cookie parameters.
长度 - 位 16-31。整个参数的大小,包括类型、长度和状态 Cookie 字段(以字节为单位)。
Length - bit 16-31. The size of the whole parameter, including the type, length and State Cookie field in bytes.
状态 Cookie - 位 31-n。该参数包含一个可变长度的cookie。有关如何创建此 cookie 的说明,请参阅RFC 2960 - 流控制传输协议文档。
State Cookie - bit 31-n. This parameter contains a cookie of variable length. For a description on how this cookie is created, see the RFC 2960 - Stream Control Transmission Protocol document.
SACK 块用于根据接收到的 TSN 告诉 DATA 块的发送者已接收到哪些块以及流中何处存在间隙。基本上,SACK 块确认它已接收到某个点(累积 TSN Ack 参数)的数据,然后为其在累积 TSN Ack 点之后接收到的所有数据添加间隙确认块。对于每个接收到的 DATA 块,不得多次发送 SACK 块。
The SACK chunk is used to tell the sender of DATA chunks which chunks has been received and where there has been a gap in the stream, based on the received TSN's. Basically, the SACK chunk acknowledges that it has received data up to a certain point (the Cumulative TSN Ack parameter), and then adds Gap Ack Blocks for all of the data that it has received after the Cumulative TSN Ack point. A SACK chunk must not be sent more than once for every DATA chunk that is received.
类型 - 位 0-7。对于 SACK 块,此标头始终设置为 3。
Type - bit 0-7. This header is always set to 3 for SACK chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。块长度是整个块的长度,包括标头中的所有内容和所有参数。
Chunk Length - bit 16-31. The chunk length is the length of the whole chunk, including everything in the headers and all the parameters.
累积 TSN Ack - 位 32-63。这是累积 TSN Ack 参数,用于确认数据。数据块接收器将使用此字段告诉发送主机它已收到到目前为止关联点的所有数据。在这一点之后,所有没有被间隙确认块明确确认的数据基本上将被认为是下落不明的。
Cumulative TSN Ack - bit 32-63. This is the Cumulative TSN Ack parameter, which is used to acknowledge data. The DATA chunk receiver will use this field to tell the sending host that it has received all data up to this point of the association. After this point, all data that has not been specifically acknowledged by the Gap Ack Blocks will, basically, be considered unaccounted for.
通告的接收器窗口信用 (a_rwnd) - 位 64-95。a_rwnd 字段与 INIT 和 INIT ACK 块中的 a_rwnd 基本相同,但可用于升高或降低 a_rwnd 值。请阅读RFC 2960 - 流控制传输协议文档中的更多内容。
Advertised Receiver Window Credit (a_rwnd) - bit 64-95. The a_rwnd field is basically the same as the a_rwnd in the INIT and INIT ACK chunks, but can be used to raise or lower the a_rwnd value. Please read more in the RFC 2960 - Stream Control Transmission Protocol document about this.
间隙确认块的数量 - 位 96-111。该块中列出的间隙确认块的数量。每个间隙确认块占用块中的 32 位。
Number of Gap Ack Blocks - bit 96-111. The number of Gap Ack Blocks listed in this chunk. Each Gap Ack Block takes up 32 bits in the chunk.
重复 TSN 的数量 - 位 112-127。已复制的 DATA 块的数量。每个重复的 TSN 都列在块中的 Gap Ack 块之后,并且每个 TSN 需要 32 位来发送。
Number of Duplicate TSNs - bit 112-127. The number of DATA chunks that has been duplicated. Each duplicated TSN is listed after the Gap Ack Blocks in the chunk, and each TSN takes 32 bits to send.
间隙确认块 #1 开始 - 位 128-143。这是 SACK 块中的第一个 Gap Ack 块。如果接收到的数据块 TSN 编号中没有间隙,则根本不会有间隙 Ack 块。然而,如果数据块被乱序接收或者某些数据块在传输到主机的过程中丢失,就会出现间隙。已发现的间隙将通过间隙确认块进行报告。间隙确认块起始点是通过将间隙确认块起始参数添加到累积 TSN 值来计算的。计算出的值是块的开始。
Gap Ack Block #1 Start - bit 128-143. This is the first Gap Ack Block in the SACK chunk. If there are no gaps in the received DATA chunk TSN numbers, there will be no Gap Ack Blocks at all. However, if DATA chunks are received out of order or some DATA chunks where lost during transit to the host, there will be gaps. The gaps that has been seen will be reported with Gap Ack Blocks. The Gap Ack Block start point is calculated by adding the Gap Ack Block Start parameter to the Cumulative TSN value. The calculated value is the start of the block.
间隙确认块 #1 结束 - 位 144-159。该值报告流中第一个间隙确认块的结尾。已接收到 TSN 在 Gap Ack Block Start 和 Gap Ack Block End 之间的所有 DATA 块。Gap Ack Block End 值与 Start 参数一样添加到 Cumulative TSN,以获得要确认的块块的实际最后一个 TSN。
Gap Ack Block #1 End - bit 144-159. This value reports the end of the first Gap Ack Block in the stream. All the DATA chunks with the TSN between the Gap Ack Block Start and the Gap Ack Block End has been received. The Gap Ack Block End value is added to the Cumulative TSN, just as the Start parameter, to get the actual last TSN of the block chunks to be Acknowledged.
间隙确认块 #N 起始 - 位变量。对于间隙确认块数量参数中计数的每个间隙确认块,添加一个间隙确认块,直到最后 N 个块。即,如果间隙确认块数=2,则SACK块中将有两个间隙确认块。这是最后一个,包含与 Gap Ack Block #1 Start 相同类型的值。
Gap Ack Block #N Start - bits variable. For every Gap Ack Block counted in the Number of Gap Ack Blocks parameter, one Gap Ack Block is added, until the final N block. Ie, if Number of Gap Ack Blocks = 2, then there will be two Gap Ack Blocks in the SACK chunk. This is the last one simply, and contains the same type of value as the Gap Ack Block #1 Start.
间隙确认块 #N 结束 - 位变量。与 Gap Ack Block #N End 相同,但用于间隙的末尾。
Gap Ack Block #N End - bits variable. Same as for the Gap Ack Block #N End, but for the end of the gap.
重复的 TSN #1 - 位变量。这些字段报告重复的 TSN,在这种情况下,我们已经收到了特定的块,但多次收到相同的 TSN。这可能是路由器故障(重新传输已发送的数据)或从发送端点重新传输的情况,或许多其他可能性。重复 TSN 的每个实例都应报告一次。例如,如果在确认第一个 TSN 之后收到了 2 个重复的 TSN,则应在下一个发送的 SACK 消息中发送这些重复的 TSN 中的每一个。如果在发送第二个 SACK 后出现更多重复的 TSN,则应将新的重复项添加到下一个 SACK 中,依此类推。
Duplicate TSN #1 - bits variable. These fields report a duplicate TSN, in which case we have already received a specific chunk, but receive the same TSN several times more. This can either be router glitches (retransmitting already sent data) or a case of retransmission from the sending endpoint, or a score of other possibilities. Each instance of a duplicate TSN should be reported once. For example, if 2 duplicate TSN's has been received after acknowledging the first one, each of these duplicate TSN's should be sent sent in the next SACK message that is being sent. If even more duplicate TSN's should appear after this second SACK is sent, the new duplicates should be added in the next SACK, and so on.
重复的 TSN #X - 位变量。这是最后一个重复的 TSN 参数,包含与第一个参数相同类型的信息。
Duplicate TSN #X - bits variable. This is the last duplicate TSN parameter, containing the same type of information as the first parameter.
当连接的端点之一想要关闭当前关联时,会发出 SHUTDOWN 块。发送方必须在发送 SHUTDOWN 块之前清空其所有发送缓冲区,并且之后不得再发送任何 DATA 块。接收方还必须清空其发送缓冲区,然后发送响应的 SHUTDOWN ACK 块。
The SHUTDOWN chunk is issued when one of the endpoints of a connection wants to close the current association. The sending party must empty all of its sending buffers before sending the SHUTDOWN chunk, and must not send any more DATA chunks afterwards. The receiver must also empty its sending buffers and must then send the responding SHUTDOWN ACK chunk.
类型 - 位 0-7。对于 SHUTDOWN 块,此标头始终设置为 7。
Type - bit 0-7. This header is always set to 7 for SHUTDOWN chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。块长度是整个数据包的长度,包括累积 TSN Ack 参数。SHUTDOWN 块的长度应始终为 8。
Chunk Length - bit 16-31. The chunk length is the length of the whole packet, including the Cumulative TSN Ack parameter. The length of the SHUTDOWN chunk should always be 8.
累积 TSN Ack - 位 32-63。这是一个累积 TSN Ack 字段,与 SACK 块中的相同。累积 TSN 确认确认从对端端点按顺序接收到的最后一个 TSN。该参数不确认 Gap Ack 块,SHUTDOWN 块的其余部分也不能确认。先前确认的 SHUTDOWN 块中缺少间隙确认块不应被解释为先前确认的块再次丢失。
Cumulative TSN Ack - bit 32-63. This is a Cumulative TSN Ack field, just the same as in the SACK chunk. The Cumulative TSN Ack acknowledges the last TSN received in sequence from the opposite endpoint. This parameter does not, nor can the rest of the SHUTDOWN chunk either, acknowledge Gap Ack Blocks. The lack of a Gap Ack Block in the SHUTDOWN chunk that was acknowledged before should not be interpreted as if the previously acknowledged block was lost again.
SHUTDOWN ACK 块用于确认已接收到的 SHUTDOWN 块。在发送 SHUTDOWN ACK 块之前,应发送发送缓冲区中的所有数据,但缓冲区不得接受来自应用程序的任何新数据。SCTP 不像 TCP 那样支持半开连接。
The SHUTDOWN ACK chunk is used to acknowledge a SHUTDOWN chunk that has been received. Before the SHUTDOWN ACK chunk is sent, all data in the sending buffers should be sent, but the buffers must not accept any new data from the application. SCTP does not support half-open connections as TCP does.
类型 - 位 0-7。对于 SHUTDOWN ACK 块,此标头始终设置为 8。
Type - bit 0-7. This header is always set to 8 for SHUTDOWN ACK chunks.
块标志 - 位 8-15。今天没有使用。可能适用于变更。有关详细信息, 请参阅SCTP 通用和通用标头。
Chunk flags - bit 8-15. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
块长度 - 位 16-31。块长度是整个块的长度。SHUTDOWN ACK 块的长度应始终为 4。
Chunk Length - bit 16-31. The chunk length is the length of the whole chunk. The length of the SHUTDOWN ACK chunk should always be 4.
SHUTDOWN COMPLETE 块由 SHUTDOWN 的发起主机发送,以响应 SHUTDOWN ACK 块。发送此消息是为了确认协会最终关闭。
The SHUTDOWN COMPLETE chunk is sent, by the originating host of the SHUTDOWN, in response to the SHUTDOWN ACK chunk. It is sent to acknowledge that the association is finally closed.
类型 - 位 0-7。对于 SHUTDOWN COMPLETE 块,始终设置为 14。
Type - bit 0-7. Always set to 14 for SHUTDOWN COMPLETE chunks.
保留 - 位 8-14。今天没有使用。可能适用于变更。有关详细信息, 请参阅 SCTP 通用和通用标头。
Reserved - bit 8-14. Not used today. Might be applicable for change. See SCTP Common and generic headers for more information.
T 位 - 位 15。T 位未设置为表示发送主机具有与此连接关联的传输控制块 (TCB),并且该连接已被破坏。如果设置了 T 位,则无需销毁 TCB。
T-bit - bit 15. The T-bit is not set to signal that the sending host had a Transmission Control Block (TCB) associated with this connection and that it destroyed. If the T-bit was set, it had no TCB to destroy.
长度 - 位 16-31。对于 SHUTDOWN COMPLETE 块,该值始终设置为 4,因为只要不对标准进行更新,该块就永远不会更大。
Length - bit 16-31. This is always set to 4 for SHUTDOWN COMPLETE chunks, since the chunk should never be any larger, as long as no updates to the standards are made.
当涉及到路由部分时,TCP/IP 的复杂性已经大大增加。一开始,大多数人认为目的地驱动的路由就足够了。然而,在过去的几年里,这变得越来越复杂。如今,Linux 基本上可以在 IP 标头中的每个字段或位上进行路由,甚至还可以基于 TCP、UDP 或 ICMP 标头进行路由。这称为基于策略的路由或高级路由。
TCP/IP has grown in complexity quite a lot when it comes to the routing part. In the beginning, most people thought it would be enough with destination driven routing. The last few years, this has become more and more complex however. Today, Linux can route on basically every single field or bit in the IP header, and even based on TCP, UDP or ICMP headers as well. This is called policy based routing, or advanced routing.
这只是关于如何执行目的地驱动路由的简要讨论。当我们从发送主机发送数据包时,就会创建该数据包。此后,计算机查看数据包目标地址并将其与现有的路由表进行比较。如果目标地址是本地地址,则数据包将通过其硬件 MAC 地址直接发送到该地址。如果数据包位于网关的另一侧,则数据包将发送到网关的 MAC 地址。然后网关将查看 IP 标头并查看数据包的目标地址。再次在路由表中查找目的地址,并将数据包发送到下一个网关等等,直到数据包最终到达目的地的本地网络。
This is simply a brief discussion on how the destination driven routing is performed. When we send a packet from a sending host, the packet is created. After this, the computer looks at the packet destination address and compares it to the routing table that it has. If the destination address is local, the packet is sent directly to that address via its hardware MAC address. If the packet is on the other side of a gateway, the packet is sent to the MAC address of the gateway. The gateway will then look at the IP headers and see the destination address of the packet. The destination address is looked up in the routing table again, and the packet is sent to the next gateway, et cetera, until the packet finally reaches the local network of the destination.
如您所见,此路由非常基本且简单。使用高级路由和基于策略的路由,这会变得更加复杂。我们可以根据数据包的源地址或 TOS 值等对数据包进行不同的路由。
As you can see, this routing is very basic and simple. With the advanced routing and policy based routing, this gets quite a bit more complex. We can route packets differently based on their source address for example, or their TOS value, et cetera.
本章为您提供了最新信息,以便您充分理解后续章节。已彻底检查了以下内容:
This chapter has brought you up to date to fully understand the subsequent chapters. The following has been gone through thoroughly:
TCP/IP结构
TCP/IP structure
IP 协议功能和标头。
IP protocol functionality and headers.
TCP 协议功能和标头。
TCP protocol functionality and headers.
UDP 协议功能和标头。
UDP protocol functionality and headers.
ICMP 协议功能和标头。
ICMP protocol functionality and headers.
TCP/IP 目标驱动路由。
TCP/IP destination driven routing.
当您稍后开始使用实际的防火墙规则集时,所有这些都会非常方便。所有这些信息都是组合在一起的,将导致更好的防火墙设计。
All of this will come in very handy later on when you start to work with the actual firewall rulesets. All of this information are pieces that fit together, and will lead to a better firewall design.
本章将讨论有关 IP 过滤器的理论细节、它是什么、它如何工作以及诸如在哪里放置防火墙、策略等的基本知识。
This chapter will discuss the theoretical details about an IP filter, what it is, how it works and basic things such as where to place firewalls, policies, etcetera.
本章的问题可能是,防火墙实际上应该放在哪里?在大多数情况下,这是一个简单的问题,但在大型企业环境中可能会变得更加棘手。政策应该是什么?谁应该有权访问哪里?IP过滤器到底是什么?所有这些问题都应该在本章后面得到很好的回答。
Questions for this chapter may be, where to actually put the firewall? In most cases, this is a simple question, but in large corporate environments it may get trickier. What should the policies be? Who should have access where? What is actually an IP filter? All of these questions should be fairly well answered later on in this chapter.
充分了解 IP 过滤器是什么非常重要。iptables 是一个 IP 过滤器,如果你不完全理解这一点,你将来在设计防火墙时将会遇到严重的问题。
It is important to fully understand what an IP filter is. Iptables is an IP filter, and if you don't fully understand this, you will get serious problems when designing your firewalls in the future.
IP 过滤器主要在 TCP/IP 参考堆栈的第 2 层中运行。然而,Iptables 也能够在第 3 层中工作,这实际上是当今大多数 IP 过滤器所具备的。但根据定义,IP 过滤器在第二层工作。
An IP filter operates mainly in layer 2, of the TCP/IP reference stack. Iptables however has the ability to also work in layer 3, which actually most IP filters of today have. But per definition an IP filter works in the second layer.
如果 IP 过滤器实现严格遵循定义,换句话说,它只能根据 IP 标头(源和目标地址、TOS/DSCP/ECN、TTL、协议等)过滤数据包。 IP 标头。)但是,由于 Iptables 实现并不完全严格地围绕此定义,因此它还能够根据数据包较深层(TCP、UDP 等)和较浅层(MAC 源地址)的其他标头来过滤数据包)。
If the IP filter implementation is strictly following the definition, it would in other words only be able to filter packets based on their IP headers (Source and Destionation address, TOS/DSCP/ECN, TTL, Protocol, etc. Things that are actually in the IP header.) However, since the Iptables implementation is not perfectly strict around this definition, it is also able to filter packets based on other headers that lie deeper into the packet (TCP, UDP, etc), and shallower (MAC source address).
然而有一件事,现在 iptables 的要求相当严格。它不会“跟随”流或将数据拼凑在一起。这太消耗处理器和内存了。稍后将进一步讨论其含义。它确实跟踪数据包并查看它们是否属于同一流(通过序列号、端口号等),几乎与真正的 TCP/IP 堆栈完全相同。这称为连接跟踪,因此我们可以执行诸如目标和源网络地址转换(通常称为 DNAT 和 SNAT)以及数据包状态匹配之类的操作。
There is one thing however, that iptables is rather strict about these days. It does not "follow" streams or puzzle data together. This would simply be too processor- and memoryconsuming . The implications of this will be discussed a little bit more further on. It does keep track of packets and see if they are of the same stream (via sequence numbers, port numbers, etc.) almost exactly the same way as the real TCP/IP stack. This is called connection tracking, and thanks to this we can do things such as Destination and Source Network Address Translation (generally called DNAT and SNAT), as well as state matching of packets.
正如我上面所暗示的,iptables 无法将来自不同数据包的数据相互连接(默认情况下),因此您永远无法完全确定您将始终看到完整的数据。我特别提到这一点是因为在不同的邮件列表上不断地至少有几个与 netfilter 和 iptables 相关的问题,以及如何做通常被认为是一个非常糟糕的主意的事情。例如,每次出现基于 Windows 的新病毒时,都会有几个不同的人询问如何删除包含特定字符串的所有流。这样做的坏主意是它很容易被规避。例如,如果我们匹配这样的内容:
As I implied above, iptables can not connect data from different packets to each other (per default), and hence you can never be fully certain that you will see the complete data at all times. I am specifically mentioning this since there are constantly at least a couple of questions about this on the different mailing lists pertaining to netfilter and iptables and how to do things that are generally considered a really bad idea. For example, every time there is a new windows based virus, there are a couple of different persons asking how to drop all streams containing a specific string. The bad idea about this is that it is so easily circumvented. For example if we match for something like this:
执行程序
cmd.exe
现在,如果病毒/漏洞编写者足够聪明,可以将数据包大小设置得非常小,以致 cmd 出现在一个数据包中,而 .exe 出现在下一个数据包中,会发生什么情况?或者,如果数据包必须通过本身具有如此小的数据包大小的网络,该怎么办?是的,由于这些字符串匹配函数无法跨数据包边界工作,因此数据包无论如何都会通过。
Now, what happens if the virus/exploit writer is smart enough to make the packet size so small that cmd winds up in one packet, and .exe winds up in the next packet? Or what if the packet has to travel through a network that has this small a packet size on its own? Yes, since these string matching functions is unable to work across packet boundaries, the packet will get through anyway.
你们中的一些人现在可能会问自己,为什么我们不简单地使字符串匹配等能够跨数据包边界读取?实际上相当简单。这对处理器时间来说成本太高。连接跟踪已经占用了大量处理器时间,令人完全放心。为连接跟踪添加另一层额外的复杂性(例如这样的)可能会导致比我们任何人预期的更多的防火墙消失。不要考虑每台机器上这个简单的任务将使用多少内存。
Some of you may now be asking yourself, why don't we simply make it possible for the string matches, etcetera to read across packet boundaries? It is actually fairly simple. It would be too costly on processor time. Connection tracking is already taking way to much processor time to be totally comforting. To add another extra layer of complexity to connection tracking, such as this, would probably kill more firewalls than anyone of us could expect. Not to think of how much memory would be used for this simple task on each machine.
未开发此功能还有第二个原因。有一种技术叫做代理。代理是为了处理较高层的流量而开发的,因此可以更好地满足这些要求。代理最初是为了处理下载和经常使用的页面而开发的,并帮助您充分利用缓慢的互联网连接。例如,鱿鱼是一个网络代理。想要下载页面的人发送请求,代理要么抓取请求,要么接收请求并打开与网络浏览器的连接,然后连接到网络服务器并下载文件,当它下载完文件或页面,它将其发送给客户端。现在,如果第二个浏览器想要再次读取同一页面,文件或页面已经下载到代理,可以直接发送,并为我们节省带宽。
There is also a second reason for this functionality not being developed. There is a technology called proxies. Proxies were developed to handle traffic in the higher layers, and are hence much better at fullfilling these requirements. Proxies were originally developed to handle downloads and often used pages and to help you get the most out of slow Internet connections. For example, Squid is a webproxy. A person who wants to download a page sends the request, the proxy either grabs the request or receives the request and opens the connection to the web browser, and then connects to the webserver and downloads the file, and when it has downloaded the file or page, it sends it to the client. Now, if a second browser wants to read the same page again, the file or page is already downloaded to the proxy, and can be sent directly, and saves bandwidth for us.
正如您可能了解的那样,代理还具有很多功能可以查看其下载的文件的实际内容。正因为如此,他们更擅长查看整个流、文件、页面等的内部。
As you may understand, proxies also have quite a lot of functionality to go in and look at the actual content of the files that it downloads. Because of this, they are much better at looking inside the whole streams, files, pages etc.
现在,在警告您在 iptables 和 netfilter 中进行 7 级过滤的固有问题之后,实际上有一组补丁可以解决这些问题。这称为http://l7-filter.sourceforge.net/。它可以用来匹配很多第7层协议,但主要是与QoS和流量计费一起使用,尽管它也可以用于纯粹的过滤。l7-filter 仍然是实验性的,并且是在内核和 netfilter 核心团队之外开发的,因此您不会在这里听到更多关于它的信息。
Now, after warning you about the inherent problems of doing level 7 filtering in iptables and netfilter, there is actually a set of patches that has attacked these problems. This is called http://l7-filter.sourceforge.net/. It can be used to match on a lot of layer 7 protocols but is mainly to be used together with QoS and traffic accounting, even though it can be used for pure filtering as well. The l7-filter is still experimental and developed outside the kernel and netfilter coreteam, and hence you will not hear more about it here.
为了充分理解接下来的章节,必须理解一些通用术语和表达方式,包括有关 TCP/IP 章节的大量细节。这是 IP 过滤中最常用术语的列表。
To fully understand the upcoming chapters there are a few general terms and expressions that one must understand, including a lot of details regarding the TCP/IP chapter. This is a listing of the most common terms used in IP filtering.
丢弃/拒绝 - 当数据包被丢弃或拒绝时,它只是被删除,并且不会采取进一步的操作。没有回复告诉主机它已被丢弃,也没有以任何方式通知数据包的接收主机。数据包就这样消失了。
Drop/Deny - When a packet is dropped or denied, it is simply deleted, and no further actions are taken. No reply to tell the host it was dropped, nor is the receiving host of the packet notified in any way. The packet simply disappears.
拒绝 - 这与丢弃或拒绝目标或策略基本相同,只是我们还向发送被丢弃数据包的主机发送回复。回复可以是指定的,也可以自动计算为某个值。(到目前为止,不幸的是,还没有 iptables 功能来发送数据包,通知接收主机被拒绝的数据包发生了什么(即,执行拒绝目标的相反操作)。这在某些情况下非常好,因为接收主机主机无法阻止拒绝服务攻击的发生。)
Reject - This is basically the same as a drop or deny target or policy, except that we also send a reply to the host sending the packet that was dropped. The reply may be specified, or automatically calculated to some value. (To this date, there is unfortunately no iptables functionality to also send a packet notifying the receiving host of the rejected packet what happened (ie, doing the reverse of the Reject target). This would be very good in certain circumstances, since the receiving host has no ability to stop Denial of Service attacks from happening.)
状态 - 与整个数据包流相比的数据包的特定状态。例如,如果该数据包是防火墙看到或了解的第一个数据包,则将其视为新数据包(TCP 连接中的 SYN 数据包),或者如果它是防火墙了解的已建立连接的一部分,则将其视为新数据包待成立。通过连接跟踪系统了解状态,该系统跟踪所有会话。
State - A specific state of a packet in comparison to a whole stream of packets. For example, if the packet is the first that the firewall sees or knows about, it is considered new (the SYN packet in a TCP connection), or if it is part of an already established connection that the firewall knows about, it is considered to be established. States are known through the connection tracking system, which keeps track of all the sessions.
链 - 链包含应用于遍历该链的数据包的规则集。每个链都有特定的用途(例如,它连接到哪个表,该表指定该链能够做什么),以及特定的应用程序区域(例如,仅转发的数据包,或仅发往该主机的数据包)。在iptables中,有几种不同的链,将在后面的章节中深入讨论。
Chain - A chain contains a ruleset of rules that are applied on packets that traverses the chain. Each chain has a specific purpose (e.g., which table it is connected to, which specifies what this chain is able to do), as well as a specific application area (e.g., only forwarded packets, or only packets destined for this host). In iptables, there are several different chains, which will be discussed in depth in later chapters.
表 - 每个表都有特定的用途,在 iptables 中有 4 个表。raw、nat、mangle 和过滤表。例如,filter表专门用于过滤数据包,而nat表专门用于NAT(网络地址转换)数据包。
Table - Each table has a specific purpose, and in iptables there are 4 tables. The raw, nat, mangle and filter tables. For example, the filter table is specifically designed to filter packets, while the nat table is specifically designed to NAT (Network Address Translation) packets.
匹配 - 当涉及到 IP 过滤时,这个词可以有两种不同的含义。第一个含义是单个匹配,它告诉规则该标头必须包含此信息。例如,--source 匹配告诉我们源地址必须是特定的网络范围或主机地址。第二个含义是整个规则是否匹配。如果数据包匹配整个规则,则将执行跳转或目标指令(例如,数据包将被丢弃。)
Match - This word can have two different meanings when it comes to IP filtering. The first meaning would be a single match that tells a rule that this header must contain this and this information. For example, the --source match tells us that the source address must be a specific network range or host address. The second meaning is if a whole rule is a match. If the packet matches the whole rule, the jump or target instructions will be carried out (e.g., the packet will be dropped.)
目标 - 通常为规则集中的每个规则设置一个目标。如果规则完全匹配,目标规范会告诉我们如何处理数据包。例如,我们是否应该删除或接受它,或者对其进行 NAT 等。还有一种称为跳转规范的内容,有关详细信息,请参阅此列表中的跳转说明。最后一点,每个规则可能没有目标或跳转,但也可能有。
Target - There is generally a target set for each rule in a ruleset. If the rule has matched fully, the target specification tells us what to do with the packet. For example, if we should drop or accept it, or NAT it, etc. There is also something called a jump specification, for more information see the jump description in this list. As a last note, there might not be a target or jump for each rule, but there may be.
规则 - 在大多数 IP 过滤器实现(包括 iptables 实现)中,规则是一组匹配或多个匹配以及单个目标。有一些实现允许您对每个规则使用多个目标/操作。
Rule - A rule is a set of a match or several matches together with a single target in most implementations of IP filters, including the iptables implementation. There are some implementations which let you use several targets/actions per rule.
规则集 - 规则集是放入整个 IP 过滤器实现中的完整规则集。对于 iptables,这包括过滤器、nat、raw 和 mangle 表以及所有后续链中设置的所有规则。大多数时候,它们被写在某种配置文件中。
Ruleset - A ruleset is the complete set of rules that are put into a whole IP filter implementation. In the case of iptables, this includes all of the rules set in the filter, nat, raw and mangle tables, and in all of the subsequent chains. Most of the time, they are written down in a configuration file of some sort.
跳转 - 跳转指令与目标密切相关。跳转指令的编写方式与 iptables 中的目标完全相同,不同之处在于您不编写目标名称,而是编写另一个链的名称。如果规则匹配,则数据包将被发送到第二条链并在该链中照常进行处理。
Jump - The jump instruction is closely related to a target. A jump instruction is written exactly the same as a target in iptables, with the exception that instead of writing a target name, you write the name of another chain. If the rule matches, the packet will hence be sent to this second chain and be processed as usual in that chain.
连接跟踪 - 实现连接跟踪的防火墙能够简单地跟踪连接/流。这样做的能力通常是在大量处理器和内存使用的影响下完成的。不幸的是,这在 iptables 中也是如此,但是我们已经做了很多工作来解决这个问题。然而,好的一面是,通过防火墙策略的实施者正确使用连接跟踪,防火墙将更加安全。
Connection tracking - A firewall which implements connection tracking is able to track connections/streams simply put. The ability to do so is often done at the impact of lots of processor and memory usage. This is unfortunately true in iptables as well, but much work has been done to work on this. However, the good side is that the firewall will be much more secure with connection tracking properly used by the implementer of the firewall policies.
接受 - 接受数据包并让其通过防火墙规则。这与丢弃或拒绝目标以及拒绝目标相反。
Accept - To accept a packet and to let it through the firewall rules. This is the opposite of the drop or deny targets, as well as the reject target.
策略 - 在实施防火墙时,我们大多数时候都会谈论两种策略。首先,我们有链策略,它告诉防火墙实现在没有与数据包匹配的规则的情况下对数据包采取的默认行为。这是我们将在本书中使用的该词的主要用法。第二种类型的策略是我们可能已编写文档的安全策略,例如针对整个公司或针对此特定网段的安全策略。安全策略是非常好的文档,需要在开始实际实施防火墙之前仔细考虑并正确研究。
Policy - There are two kinds of policies that we speak about most of the time when implementing a firewall. First we have the chain policies, which tells the firewall implementation the default behaviour to take on a packet if there was no rule that matched it. This is the main usage of the word that we will use in this book. The second type of policy is the security policy that we may have written documentation on, for example for the whole company or for this specific network segment. Security policies are very good documents to have thought through properly and to study properly before starting to actually implement the firewall.
规划防火墙时首先要考虑的步骤之一是它们的位置。这应该是一个相当简单的步骤,因为无论如何,大多数网络都应该被很好地分段。首先想到的地方之一是本地网络和互联网之间的网关。这是一个安全应该相当严密的地方。此外,在较大的网络中,通过防火墙将不同的部门彼此分开可能是一个好主意。例如,为什么开发团队应该访问人力资源网络,或者为什么不保护经济部门免受其他网络的影响?简而言之,您不希望愤怒的员工拿着解雇通知书篡改薪资数据库。
One of the first steps to think about when planning the firewall is their placement. This should be a fairly simple step since mostly your networks should be fairly well segmented anyway. One of the first places that comes to mind is the gateway between your local network(s) and the Internet. This is a place where there should be fairly tight security. Also, in larger networks it may be a good idea to separate different divisions from each other via firewalls. For example, why should the development team have access to the human resources network, or why not protect the economic department from other networks? Simply put, you don't want an angry employee with the pink slip tampering with the salary databases.
简而言之,上述意味着您应该尽可能地规划您的网络,并将它们规划为隔离的。特别是如果网络是中型到大型(100 个工作站或更多,基于网络的不同方面)。在这些较小的网络之间,尝试放置仅允许您想要的流量类型的防火墙。
Simply put, the above means that you should plan your networks as well as possible, and plan them to be segregated. Especially if the network is medium- to big-sized (100 workstations or more, based on different aspects of the network). In between these smaller networks, try to put firewalls that will only allow the kind of traffic that you would like.
如果您有可以从 Internet 访问的服务器,那么在您的网络中创建非军事区 (DMZ) 也是一个好主意。DMZ 是一个带有服务器的小型物理网络,它是极端封闭的。这降低了任何人实际进入 DMZ 中的计算机的风险,并且降低了任何人实际进入并从外部下载任何木马等的风险。之所以被称为非军事区,是因为它们必须从内部和外部都可以到达,因此它们是一种灰色区域(简称DMZ)。
It may also be a good idea to create a De-Militarized Zone (DMZ) in your network in case you have servers that are reached from the Internet. A DMZ is a small physical network with servers, which is closed down to the extreme. This lessens the risk of anyone actually getting in to the machines in the DMZ, and it lessens the risk of anyone actually getting in and downloading any trojans etc. from the outside. The reason that they are called de-militarized zones is that they must be reachable from both the inside and the outside, and hence they are a kind of grey zone (DMZ simply put).
有多种方法可以在防火墙中设置策略和默认行为,本节将讨论您在实际开始实施防火墙之前应该考虑的实际理论,并帮助您充分考虑您的决定程度。
There are a couple of ways to set up the policies and default behaviours in a firewall, and this section will discuss the actual theory that you should think about before actually starting to implement your firewall, and helping you to think through your decisions to the fullest extent.
在我们开始之前,您应该了解大多数防火墙都有默认行为。例如,如果特定链中没有规则匹配,则可以默认删除或接受该规则。不幸的是,每个链只有一个策略,但如果我们希望每个网络接口等有不同的策略,这通常很容易解决。
Before we start, you should understand that most firewalls have default behaviours. For example, if no rule in a specific chain matches, it can be either dropped or accepted per default. Unfortunately, there is only one policy per chain, but this is often easy to get around if we want to have different policies per network interface etc.
我们通常使用两种基本策略。要么我们放弃除我们指定的内容之外的所有内容,要么我们接受除我们明确删除的内容之外的所有内容。大多数时候,我们最感兴趣的是放弃政策,然后接受我们想要特别允许的一切。这意味着默认情况下防火墙更加安全,但这也可能意味着您需要做更多的工作才能让防火墙正常运行。
There are two basic policies that we normally use. Either we drop everything except that which we specify, or we accept everything except that which we specifically drop. Most of the time, we are mostly interested in the drop policy, and then accepting everything that we want to allow specifically. This means that the firewall is more secure per default, but it may also mean that you will have much more work in front of you to simply get the firewall to operate properly.
您要做的第一个决定就是简单地弄清楚您应该使用哪种类型的防火墙。安全问题有多大?什么样的应用程序必须能够通过防火墙?某些应用程序对防火墙来说是可怕的,原因很简单,它们会协商用于控制会话内数据流的端口。这使得防火墙很难知道要打开哪些端口。最常见的应用程序可与 iptables 配合使用,但不幸的是,更罕见的应用程序至今仍无法使用。
Your first decision to make is to simply figure out which type of firewall you should use. How big are the security concerns? What kind of applications must be able to get through the firewall? Certain applications are horrible to firewalls for the simple reason that they negotiate ports to use for data streams inside a control session. This makes it extremely hard for the firewall to know which ports to open up. The most common applications works with iptables, but the more rare ones do not work to this day, unfortunately.
还有一些应用程序只能部分运行,例如 ICQ。正常的 ICQ 使用效果很好,但聊天或文件发送功能则不行,因为它们需要特定的代码来处理协议。由于 ICQ 协议不是标准化的(它们是专有的并且可能随时更改),因此大多数 IP 过滤器都选择将 ICQ 协议处理程序排除在外,或者作为可应用于防火墙的补丁。Iptables 选择将它们保留为单独的补丁。 There are also some applications that work partially, such as ICQ. Normal ICQ usage works perfectly, but not the chat or file sending functions, since they require specific code to handle the protocol. Since the ICQ protocols are not standardized (they are proprietary and may be changed at any time) most IP filters have chosen to either keep the ICQ protocol handlers out, or as patches that can be applied to the firewalls. Iptables have chosen to keep them as separate patches. |
应用分层安全措施也可能是一个好主意,到目前为止我们实际上已经部分讨论过。我们的意思是,您应该同时使用尽可能多的安全措施,并且不要依赖任何一种单一的安全概念。将此作为安全性的基本概念将至少将安全性提高十倍。举个例子,让我们看一下这个。
It may also be a good idea to apply layered security measures, which we have actually already discussed partially so far. What we mean with this, is that you should use as many security measures as possible at the same time, and don't rely on any one single security concept. Having this as a basic concept for your security will increase security tenfold at least. For an example, let's look at this.
正如您所看到的,在本示例中,我选择将 Cisco PIX 防火墙放置在所有三个网络连接的外围。如果需要,它可以对内部 LAN 以及 DMZ 进行 NAT。它还可能阻止除 http 返回流量以及 ftp 和 ssh 流量之外的所有传出流量。它可以允许来自 LAN 和 Internet 的传入 http 流量,以及来自 LAN 的 ftp 和 ssh 流量。除此之外,我们注意到每个网络服务器都基于 Linux,因此也可以在每台机器上添加 iptables 和 netfilter,并在这些机器上添加相同的基本策略。这样,如果有人设法破坏了 Cisco PIX,我们仍然可以在每台计算机上本地依赖 netfilter 防火墙,反之亦然。这允许所谓的分层安全性。
As you can see, in this example I have in this example chosen to place a Cisco PIX firewall at the perimeter of all three network connections. It may NAT the internal LAN, as well as the DMZ if necessary. It may also block all outgoing traffic except http return traffic as well as ftp and ssh traffic. It can allow incoming http traffic from both the LAN and the Internet, and ftp and ssh traffic from the LAN. On top of this, we note that each webserver is based on Linux, and can hence throw iptables and netfilter on each of the machines as well and add the same basic policies on these. This way, if someone manages to break the Cisco PIX, we can still rely on the netfilter firewalls locally on each machine, and vice versa. This allows for so called layered security.
除此之外,我们可以 在每台机器上添加Snort 。Snort 是一个优秀的开源网络入侵检测系统(NIDS),它在它看到的数据包中查找签名,如果它看到某种攻击或入侵的签名,它可以向管理员发送电子邮件并通知他,甚至对攻击做出主动响应,例如封锁攻击来源的IP。应该注意的是,不应轻易使用主动响应,因为 snort 具有报告大量误报的不良行为(例如,报告实际上不是攻击的攻击)。
On top of this, we may add Snort on each of the machines. Snort is an excellent open source network intrusion detection system (NIDS) which looks for signatures in the packets that it sees, and if it sees a signature of some kind of attack or breakin it can either e-mail the administrator and notify him about it, or even make active responses to the attack such as blocking the IP from which the attack originated. It should be noted that active responses should not be used lightly since snort has a bad behaviour of reporting lots of false positives (e.g., reporting an attack which is not really an attack).
在网络服务器前面添加一个代理来捕获一些坏数据包也可能是一个好主意,这也可能是为所有本地生成的网络连接添加的可能性。通过网络代理,您可以缩小员工网络流量使用的范围,并在一定程度上限制他们的网络使用。至于您自己的网络服务器的网络代理,您可以使用它来阻止一些最明显的连接通过。可能值得使用的一个好的代理是Squid。
It could also be a good idea to throw in an proxy in front of the webservers to catch some of the bad packets as well, which could also be a possibility to throw in for all of the locally generated webconnections. With a webproxy you can narrow down on traffic used by webtraffic from your employees, as well as restrict their webusage to some extent. As for a webproxy to your own webservers, you can use it to block some of the most obvious connections to get through. A good proxy that may be worth using is the Squid.
另一种可以采取的预防措施是安装Tripwire。这是一种优秀的最后一道防线应用程序,它通常被认为是主机入侵检测系统。它的作用是对配置文件中指定的所有文件进行校验,然后偶尔从 cron 运行一次,以查看所有指定的文件是否与以前相同,或者没有以非法方式更改。换句话说,该程序将能够查明是否有人真正能够侵入并篡改系统。建议在所有网络服务器上运行它。
Another precaution that one can take is to install Tripwire. This is an excellent last line of defense kind of application, it is generally considered to be a Host Intrusion Detection System. What it does is to make checksums of all the files specified in a configuration file, and then it is run from cron once in a while to see that all of the specified files are the same as before, or have not changed in an illegit way. This program will in other words be able to find out if anyone has actually been able to get through and tampered with the system. A suggestion is to run this on all of the webservers.
最后要注意的一点是,正如我们所知,遵循标准总是一件好事。正如您已经在 ICQ 示例中看到的那样,如果您不使用标准化系统,事情可能会出现严重错误。对于您自己的环境,这在某种程度上可以忽略,但如果您正在运行宽带服务或调制解调器池,它就变得更加重要。通过您进行联系的人必须始终能够依赖您的标准化,并且您不能期望每个人都运行您选择的特定操作系统。有些人想运行 Windows,有些人想运行 Linux 甚至 VMS 等等。如果您将安全性建立在专有系统上,那么您就会遇到麻烦。
One last thing to note is that it is always a good thing to follow standards, as we know. As you have already seen with the ICQ example, if you don't use standardized systems, things can go terribly wrong. For your own environments, this can be ignored to some extent, but if you are running a broadband service or modempool, it gets all the more important. People who connect through you must always be able to rely on your standardization, and you can't expect everyone to run the specific operating system of your choice. Some people want to run Windows, some want to run Linux or even VMS and so on. If you base your security on proprietary systems, you are in for some trouble.
瑞典出现的某些宽带服务就是一个很好的例子,这些服务的很多安全性都基于微软网络登录。一开始这听起来像是一个好主意,但是一旦我们开始考虑其他操作系统等,这就不再是一个好主意了。运行 Linux 的人如何上网?还是VAX/VMS?还是HP/UX?对于 Linux,当然可以做到这一点,如果不是因为网络管理员通过简单地阻止运行 Linux 的任何人来拒绝他们使用宽带服务。然而,这本书并不是关于什么是最好的神学讨论,所以让我们把它作为一个例子来说明为什么使用非标准是一个坏主意。
A good example of this is certain broadband services that have popped up in Sweden who base lots of security on Microsoft network logon. This may sound like a great idea to begin with, but once we start considering other operating systems and so on, this is no longer such a good idea. How will someone running Linux get online? Or VAX/VMS? Or HP/UX? With Linux it can be done of course, if it wasn't for the fact that the network administrator refuses anyone to use the broadband service if they are running linux by simply blocking them in such case. However, this book is not a theological discussion of what is best, so let's leave it as an example of why it is a bad idea to use non-standards.
本章介绍了一些可以用来保护网络、工作站和服务器的基本 IP 过滤和安全措施。提出了以下主题:
This chapter has gone through several of the basic IP filtering and security measures that you can take to secure your networks, workstations and servers. The following subjects have been brought up:
IP过滤的使用
IP filtering usage
IP过滤策略
IP filtering policies
网络规划
Network planning
防火墙规划
Firewall planning
分层安全技术
Layered security techniques
网络分段
Network segmentation
在下一章中,我们将快速了解什么是网络地址转换 (NAT),之后我们将开始仔细研究 Iptables 及其功能,并开始实际操作这个野兽。
In the next chapter we will take a quick look at what Network Address Translation (NAT) is, and after that we will start looking closer at Iptables and it's functionality and actually start getting hands on with the beast.
迄今为止,NAT 似乎是 Linux 和 Iptables 最大的吸引力之一。许多小公司和个人用户选择使用这些解决方案,而不是使用相当昂贵的第三方解决方案(例如 Cisco PIX 等)。主要原因之一是它便宜且安全。它需要一台旧计算机、一个可以从 Internet 免费下载的相当新的 Linux 发行版、一两张备用网卡和电缆。
NAT is one of the biggestattractions of Linux and Iptables to this day it seems. Instead of using fairly expensive third party solutions such as Cisco PIX etc, a lot of smaller companies and personal users have chosen to go with these solutions instead. One of the main reasons is that it is cheap, and secure. It requires an old computer, a fairly new Linux distribution which you can download for free from the Internet, a spare network card or two and cabling.
本章将介绍一些有关 NAT 的基本理论、它的用途、它的工作原理以及在开始研究这些主题之前应该考虑什么。
This chapter will describe a little bit of the basic theory about NAT, what it can be used for, how it works and what you should think about before starting to work on these subjects.
基本上,NAT 允许一台主机或多台主机以某种方式共享相同的 IP 地址。例如,假设我们有一个由 5-10 个客户端组成的本地网络。我们将它们的默认网关设置为通过 NAT 服务器。通常情况下,数据包只会由网关机器转发,但在 NAT 服务器的情况下,情况略有不同。
Basically, NAT allows a host or several hosts to share the same IP address in a way. For example, let's say we have a local network consisting of 5-10 clients. We set their default gateways to point through the NAT server. Normally the packet would simply be forwarded by the gateway machine, but in the case of an NAT server it is a little bit different.
正如我们已经说过的,NAT 服务器将数据包的源地址和目标地址转换为不同的地址。NAT 服务器接收数据包,重写源和/或目标地址,然后重新计算数据包的校验和。NAT 最常见的用法之一是 SNAT(源网络地址转换)功能。基本上,如果我们无力承担或看不到为每个客户端拥有真正的公共 IP 的任何真正想法,则在上面的示例中使用此方法。在这种情况下,我们使用本地网络的私有 IP 范围之一(例如 192.168.1.0/24),然后为本地网络打开 SNAT。然后,SNAT 会将所有 192.168.1.0 地址转换为它自己的公共 IP(例如 217.115.95.34)。这样,就会有 5-10 个或更多的客户端使用相同的共享 IP 地址。
NAT servers translates the source and destination addresses of packets as we already said to different addresses. The NAT server receives the packet, rewrites the source and/or destination address and then recalculates the checksum of the packet. One of the most common usages of NAT is the SNAT (Source Network Address Translation) function. Basically, this is used in the above example if we can't afford or see any real idea in having a real public IP for each and every one of the clients. In that case, we use one of the private IP ranges for our local network (for example, 192.168.1.0/24), and then we turn on SNAT for our local network. SNAT will then turn all 192.168.1.0 addresses into it's own public IP (for example, 217.115.95.34). This way, there will be 5-10 clients or many many more using the same shared IP address.
还有一种叫做 DNAT 的东西,在设置服务器等方面非常有帮助。首先,在节省 IP 空间方面,您可以帮助实现更大的利益,其次,您可以获得或多或少完全无法穿透的信息。以简单的方式在您的服务器和真实服务器之间设置防火墙,或者简单地为分隔成多个物理上不同服务器的多个服务器共享一个 IP。例如,我们可能在同一台计算机上运行一个包含 Web 服务器和 ftp 服务器的小型公司服务器场,而有一个物理上独立的计算机,其中包含几个不同的聊天服务,在家或在路上工作的员工可以使用这些服务来保持联系。与现场员工保持联系。然后,我们可以通过 DNAT 从外部在同一 IP 上运行所有这些服务。
There is also something called DNAT, which can be extremely helpful when it comes to setting up servers etc. First of all, you can help the greater good when it comes to saving IP space, second, you can get an more or less totally impenetrable firewall in between your server and the real server in an easy fashion, or simply share an IP for several servers that are separated into several physically different servers. For example, we may run a small company server farm containing a webserver and ftp server on the same machine, while there is a physically separated machine containing a couple of different chat services that the employees working from home or on the road can use to keep in touch with the employees that are on-site. We may then run all of these services on the same IP from the outside via DNAT.
上面的示例也基于单独的端口 NAT,或通常称为 PNAT。我们在本书中并不经常提到这一点,因为 netfilter 中的 DNAT 和 SNAT 功能已经涵盖了它。
The above example is also based on separate port NAT'ing, or often called PNAT. We don't refer to this very often throughout this book, since it is covered by the DNAT and SNAT functionality in netfilter.
在 Linux 中,实际上可以使用两种不同类型的 NAT,即 Fast-NAT 或 Netfilter-NAT。Fast-NAT是在Linux内核的IP路由代码内部实现的,而Netfilter-NAT也在Linux内核中实现,但在netfilter代码内部。由于本书不会太深入地涉及 IP 路由代码,因此除了一些注释外,我们几乎将其留在这里。Fast-NAT 通常被称为此名称,因为它比 netfilter NAT 代码快得多。它不跟踪连接,这是它的主要优点和缺点。连接跟踪需要大量的处理器能力,因此速度较慢,这是 Fast-NAT 比 Netfilter-NAT 更快的主要原因之一。正如我们也说过的,Fast-NAT 的缺点是不跟踪连接,这意味着它不能很好地对整个网络进行 SNAT,也不能对复杂的协议进行 NAT,例如 FTP、IRC 以及 Netfilter-NAT 能够很好处理的其他协议。这是可能的,但需要做的工作比 Netfilter 实现预期的要多得多。
In Linux, there are actually two separate types of NAT that can be used, either Fast-NAT or Netfilter-NAT. Fast-NAT is implemented inside the IP routing code of the Linux kernel, while Netfilter-NAT is also implemented in the Linux kernel, but inside the netfilter code. Since this book won't touch the IP routing code too closely, we will pretty much leave it here, except for a few notes. Fast-NAT is generally called by this name since it is much faster than the netfilter NAT code. It doesn't keep track of connections, and this is both its main pro and con. Connection tracking takes a lot of processor power, and hence it is slower, which is one of the main reasons that the Fast-NAT is faster than Netfilter-NAT. As we also said, the bad thing about Fast-NAT doesn't track connections, which means it will not be able to do SNAT very well for whole networks, neither will it be able to NAT complex protocols such as FTP, IRC and other protocols that Netfilter-NAT is able to handle very well. It is possible, but it will take much, much more work than would be expected from the Netfilter implementation.
最后还有一个词基本上是 SNAT 的同义词,即 Masquerade 词。在 Netfilter 中,伪装与 SNAT 几乎相同,不同之处在于伪装会自动将新源 IP 设置为传出网络接口的默认 IP 地址。
There is also a final word that is basically a synonym to SNAT, which is the Masquerade word. In Netfilter, masquerade is pretty much the same as SNAT with the exception that masquerading will automatically set the new source IP to the default IP address of the outgoing network interface.
正如我们已经在某种程度上解释的那样,使用 NAT 有很多小注意事项。主要问题是某些协议和应用程序可能根本无法工作。希望这些应用程序在您管理的网络中不太常见,在这种情况下,它应该不会造成大问题。
As we have already explained to some extent, there are quite a lot of minor caveats with using NAT. The main problem is certain protocols and applications which may not work at all. Hopefully, these applications are not too common in the networks that you administer, and in such case, it should cause no huge problems.
第二个也是较小的问题是应用程序和协议只能部分工作。这些协议比那些根本不起作用的协议更常见,这是非常不幸的,但看起来我们对此无能为力。如果继续构建复杂的协议,我们将不得不继续面对这个问题。尤其是在协议未标准化的情况下。
The second and smaller problem is applications and protocols which will only work partially. These protocols are more common than the ones that will not work at all, which is quite unfortunate, but there isn't very much we can do about it as it seems. If complex protocols continue to be built, this is a problem we will have to continue living with. Especially if the protocols aren't standardized.
在我看来,第三个也是最大的问题是,坐在 NAT 服务器后面访问互联网的用户将无法运行自己的服务器。当然,这是可以做到的,但是需要花费更多的时间和工作来进行设置。在公司中,这可能比拥有由不同员工运行的大量服务器可以通过互联网访问而无需任何监督更受欢迎。然而,对于家庭用户来说,这应该是最后避免的。作为互联网服务提供商,您永远不应该将您的客户从私有 IP 范围转换为公共 IP。它会给你带来比值得处理的更多的麻烦,并且总会有一个或另一个客户希望这个或那个协议完美地工作。如果不这样做,你就会被贬低。
The third, and largest problem, in my point of view, is the fact that the user who sits behind a NAT server to get out on the internet will not be able to run his own server. It could be done, of course, but it takes a lot more time and work to set this up. In companies, this is probably preferred over having tons of servers run by different employees that are reachable from the Internet, without any supervision. However, when it comes to home users, this should be avoided to the very last. You should never as an Internet service provider NAT your customers from a private IP range to a public IP. It will cause you more trouble than it is worth having to deal with, and there will always be one or another client which will want this or that protocol to work flawlessly. When it doesn't, you will be called down upon.
作为关于 NAT 警告的最后一点,应该提到的是 NAT 实际上或多或少只是一种 hack。NAT 是IANA制定的解决方案和其他组织指出,互联网呈指数级增长,IP 地址很快就会出现短缺。NAT 过去和现在都是解决 IPv4 问题的短期解决方案(是的,我们之前讨论过的 IP 是 IPv4 的简短版本,代表互联网协议版本 4)。IPv6 协议是解决 IPv4 地址短缺问题的长期解决方案,它还解决了大量其他问题。IPv6 有 128 位分配给它们的地址,而 IPv4 只有 32 位用于 IP 地址。地址空间的增加令人难以置信。拥有足够的 IP 地址来为地球上的每个原子设置一个 IP 地址似乎很荒谬,但另一方面,也没有人预计 IPv4 地址范围会太小。
As one last note on the caveats of NAT, it should be mentioned that NAT is actually just a hack more or less. NAT was a solution that was worked out while the IANA and other organisations noted that the Internet grew exponentially, and that the IP addresses would soon be in shortage. NAT was and is a short term solution to the problem of the IPv4 (Yes, IP which we have talked about before is a short version of IPv4 which stands for Internet Protocol version 4). The long term solution to the IPv4 address shortage is the IPv6 protocol, which also solves a ton of other problems. IPv6 has 128 bits assigned to their addresses, while IPv4 only have 32 bits used for IP addresses. This is an incredible increase in address space. It may seem like ridiculous to have enough IP addresses to set one IP address for every atom in our planet, but on the other hand, noone expected the IPv4 address range to be too small either.
这是一个小型的理论场景,我们希望在 2 个不同的网络和 Internet 连接之间有一个 NAT 服务器。我们想要做的是将两个网络相互连接,并且两个网络都应该能够互相访问并访问互联网。我们将讨论您应该考虑的硬件问题,以及在实际开始实施 NAT 机器之前您应该考虑的其他理论。
This is a small theoretical scenario where we want a NAT server between 2 different networks and an Internet connection. What we want to do is to connect 2 networks to each other, and both networks should have access to each other and the Internet. We will discuss the hardware questions you should take into consideration, as well as other theory you should think about before actually starting to implement the NAT machine.
在进一步讨论之前,我们应该首先了解构建执行 NAT 的 Linux 机器需要什么样的硬件。对于大多数较小的网络来说,这应该没有问题,但如果您开始考虑较大的网络,它实际上可以成为一个。NAT 的最大问题是它消耗资源的速度相当快。对于可能有 1-10 个用户的小型专用网络,具有32 MB 的486ram 的作用绰绰有余。但是,如果您开始拥有大约 100 名或更多用户,您应该开始考虑应该考虑哪种硬件。当然,考虑带宽使用情况以及同时打开多少个连接也是一个好主意。不过,一般来说,备用计算机就可以很好地工作,这是使用基于 Linux 的防火墙的一大优点。您可以使用剩下的旧硬件,因此与其他防火墙相比,防火墙将非常便宜。
Before we discuss anything further, we should start by looking at what kind of hardware is needed to build a Linux machine doing NAT. For most smaller networks, this should be no problem, but if you are starting to look at larger networks, it can actually become one. The biggest problem with NAT is that it eats resources quite fast. For a small private network with possibly 1-10 users, a 486 with 32 MB of ram will do more than enough. However, if you are starting to get up around 100 or more users, you should start considering what kind of hardware you should look at. Of course, it is also a good idea to consider bandwidth usage, and how many connections will be open at the same time. Generally, spare computers will do very well however, and this is one of the big pros of using a Linux based firewall. You can use old scrap hardware that you have left over, and hence the firewall will be very cheap in comparison to other firewalls.
您还需要考虑网卡。有多少个单独的网络将连接到您的 NAT/过滤器机器?大多数时候,将一个网络连接到 Internet 连接就足够了。如果您通过以太网连接到互联网,您通常应该有 2 个以太网卡等。为了可扩展性,选择相对好的品牌的 10/100 Mbit/s 网卡是一个好主意,但大多数任何类型的网卡只要 Linux 内核中有驱动程序就可以。关于这个问题的注释:避免使用或获取 Linux 内核发行版中实际上没有驱动程序的网卡。我曾多次发现在光盘上单独分发驱动程序的网卡/品牌的工作效果很差。它们一般都没有得到很好的维护,如果您一开始就让它们在您选择的内核上工作,那么它们真正在下一个主要 Linux 内核升级上工作的机会非常小。在大多数情况下,这意味着您可能必须购买更昂贵的网卡,但最终这是值得的。
You will also need to consider network cards. How many separate networks will connect to your NAT/filter machine? Most of the time it is simply enough to connect one network to an Internet connection. If you connect to the Internet via ethernet, you should generally have 2 ethernet cards, etcetera. It can be a good idea to choose 10/100 mbit/s network cards of relatively good brands for this for scalability, but most any kinds of cards will do as long as they have drivers in the Linux kernel. A note on this matter: avoid using or getting network cards that don't have drivers actually in the Linux kernel distribution. I have on several occasions found network cards/brands that have separately distributed drivers on discs that work dismally. They are generally not very well maintained, and if you get them to work on your kernel of choice to begin with, the chance that they will actually work on the next major Linux kernel upgrade is very small. This will most of the time mean that you may have to get a little bit more costly network cards, but in the end it is worth it.
请注意,如果您要在非常旧的硬件上构建防火墙,建议您至少尝试使用 PCI 总线或尽可能使用更好的总线。首先,网卡希望以后升级时可以使用。此外,ISA 总线速度极慢且占用 CPU 资源繁重。这意味着在 ISA 网卡上施加大量负载可能会毁掉您的机器。
As a note, if you are going to build your firewall on really old hardware, it is suggested that you at least try to use PCI buses or better as far as possible. First of all, the network cards will hopefully be possible to use in the future when you upgrade. Also, ISA buses are extremely slow and heavy on the CPU usage. This means that putting a lot of load onto ISA network cards can next to kill your machine.
最后,还需要考虑的一件事是您在 NAT/防火墙机器中放入了多少内存。如果可能的话,最好至少放置64 MB以上的内存,即使可以在32 MB内存上运行。NAT 的内存消耗并不是特别大,但明智的做法是添加尽可能多的内存,以防您获得的流量超出预期。
Finally, one thing more to consider is how much memory you put into the NAT/firewall machine. It is a good idea to put in at least more than 64 MB of memory if possible, even if it is possible run it on 32MB of memory. NAT isn't extremely huge on memory consumption, but it may be wise to add as much as possible just in case you will get more traffic than expected.
正如您所看到的,在硬件方面有很多需要考虑的地方。但是,说实话,大多数情况下您根本不需要考虑这些问题,除非您正在为大型网络或公司构建 NAT 机器。大多数家庭用户不需要考虑这一点,但可能或多或少地使用他们手边的任何硬件。关于这个主题没有完整的比较和测试,但只要有一点常识,你就应该表现得相当好。
As you can see, there is quite a lot to think about when it comes to hardware. But, to be completely honest, in most cases you don't need to think about these points at all, unless you are building a NAT machine for a large network or company. Most home users need not think about this, but may more or less use whatever hardware they have handy. There are no complete comparisons and tests on this topic, but you should fare rather well with just a little bit of common sense.
这看起来应该相当简单,但是,在大型网络中它可能比您最初想象的要困难。一般来说,NAT 机器应该放置在网络的外围,就像任何过滤机器一样。当然,大多数时候,这意味着 NAT 和过滤机器是同一台机器。另外值得考虑的是,如果您有非常大的网络,则可能值得将网络拆分为较小的网络,并为每个网络分配一个 NAT/过滤机器。由于 NAT 需要相当多的处理能力,这肯定有助于降低往返时间(RTT,数据包到达目的地和返回数据包返回所需的时间)。
This should look fairly simple, however, it may be harder than you originally thought in large networks. In general, the NAT machine should be placed on the perimeter of the network, just like any filtering machine out there. This, most of the time, means that the NAT and filtering machines are the same machine, of course. Also worth a thought, if you have very large networks, it may be worth splitting the network into smaller networks and assign a NAT/filtering machine for each of these networks. Since NAT takes quite a lot of processing power, this will definitely help keep round trip time (RTT, the time it takes for a packet to reach a destination and the return packet to get back) down.
在我们上面描述的示例网络中,有两个网络和一个互联网连接,换句话说,我们应该看看这两个网络有多大。如果我们可以认为它们很小,并且根据客户端的要求,在一台像样的 NAT 机器上,几百个客户端应该没有问题。否则,我们可以通过在较小的 NAT 机器上设置公共 IP,将负载分散到多台机器上,每台机器处理自己较小的网络段,然后让流量聚集在特定的仅路由机器上。当然,这要考虑到您必须为所有 NAT 机器拥有足够的公共 IP,并且它们是通过您的路由机器进行路由的。
In our example network as we described above, with two networks and an Internet connection we should, in other words, look at how large the two networks are. If we can consider them to be small and depending on what requirements the clients have, a couple of hundred clients should be no problem on a decent NAT machine. Otherwise, we could have split up the load over several machines by setting public IP's on smaller NAT machines, each handling their own smaller segment of the network and then let the traffic congregate over a specific routing only machine. This of course takes into consideration that you must have enough public IP's for all of your NAT machines, and that they are routed through your routing machine.
不幸的是,在大多数情况下,代理是 NAT 的一个普遍问题,尤其是透明代理。普通代理不会造成太大麻烦,但创建透明代理却很麻烦,尤其是在较大的网络上。第一个问题是代理需要相当多的处理能力,就像 NAT 一样。如果您要处理大量网络流量,则不建议将它们放在同一台计算机上。第二个问题是,如果您对源 IP 和目标 IP 进行 NAT,代理将无法知道要联系哪些主机。例如,客户端试图联系哪个服务器?由于所有这些信息在 NAT 转换过程中都会丢失,因为数据包在经过 NAT 处理后就无法包含该信息,因此这是一个问题。在当地,
Proxies are a general problem when it comes to NAT in most cases unfortunately, especially transparent proxies. Normal proxies should not cause too much trouble, but creating a transparent proxy is a dog to get to work, especially on larger networks. The first problem is that proxies take quite a lot of processing power, just the same as NAT does. To put both of these on the same machine is not advisable if you are going to handle large network traffic. The second problem is that if you NAT the source IP as well as the destination IP, the proxy will not be able to know what hosts to contact. E.g., which server is the client trying to contact? Since all that information is lost during the NAT translation since the packets can't contain that information as well if they are NAT'ed, it's a problem. Locally, this has been solved by adding the information in the internal data structures that are created for the packets, and hence proxies such as squid can get the information.
正如您所看到的,问题是如果您要运行透明代理,您没有太多选择。当然,有一些可能性,但实际上并不建议这样做。一种可能性是在防火墙外部创建一个代理,并创建一个路由条目,通过该计算机路由所有 Web 流量,然后在代理计算机上将数据包本地 NAT 到代理的正确端口。这样,信息会一直保留到代理计算机,并且在代理计算机上仍然可用。
As you can see, the problem is that you don't have much of a choice if you are going to run a transparent proxy. There are, of course, possibilities, but they are not advisable really. One possibility is to create a proxy outside the firewall and create a routing entry that routes all web traffic through that machine, and then locally on the proxy machine NAT the packets to the proper ports for the proxy. This way, the information is preserved all the way to the proxy machine and is still available on it.
第二种可能性是简单地在防火墙外创建一个代理,然后阻止除流向代理的流量之外的所有网络流量。这样,您将强制所有用户实际使用代理。这是一种粗略的方法,但希望它会起作用。
The second possibility is to simply create a proxy outside the firewall, and then block all webtraffic except the traffic going to the proxy. This way, you will force all users to actually use the proxy. It's a crude way of doing it, but it will hopefully work.
作为最后一步,我们应该将所有这些信息放在一起,然后看看如何解决 NAT 机器的问题。让我们看一下网络的图片及其外观。我们决定在 NAT/过滤机外部放置一个代理,如上所述,但在路由器内部计数。从某种意义上说,该区域可以视为 DMZ,NAT/过滤器是 DMZ 和两个公司网络之间的路由器。您可以在下图中看到我们正在讨论的确切布局。
As a final step, we should bring all of this information together, and see how we would solve the NAT machine then. Let's take a look at a picture of the networks and how it looks. We have decided to put a proxy just outside the NAT/filtering machine as described above, but inside counting from the router. This area could be counted upon as an DMZ in a sense, with the NAT/filter machine being a router between the DMZ and the two company networks. You can see the exact layout we are discussing in the image below.
来自 NAT 网络的所有正常流量将通过 DMZ 直接发送到路由器,路由器将流量发送到互联网。除了,是的,你猜对了,webtraffic 是在 NAT 机器的 netfilter 部分内标记的,然后根据标记路由到代理机器。让我们看看我在说什么。假设 NAT 机器看到一个 http 数据包。然后,mangle 表可用于使用 netfilter 标记(也称为 nfmark)来标记数据包。甚至稍后,当我们应该将数据包路由到路由器时,我们将能够检查路由表中的 nfmark,并根据此标记,我们可以选择将 http 数据包路由到代理服务器。然后代理服务器将对数据包进行处理。
All the normal traffic from the NAT'ed networks will be sent through the DMZ directly to the router, which will send the traffic on out to the internet. Except, yes, you guessed it, webtraffic which is instead marked inside the netfilter part of the NAT machine, and then routed based on the mark and to the proxy machine. Let's take a look at what I am talking about. Say a http packet is seen by the NAT machine. The mangle table can then be used to mark the packet with a netfilter mark (also known as nfmark). Even later when we should route the packets to our router, we will be able to check for the nfmark within the routing tables, and based on this mark, we can choose to route the http packets to the proxy server. The proxy server will then do it's work on the packets. We will touch these subjects to some extent later on in the document, even though much of the routing based part is happening inside the advanced routing topics.
NAT 机器具有可在 Internet 上使用的公共 IP,以及路由器和可能在 Internet 上可用的任何其他机器。NAT 网络内的所有机器都将使用私有 IP,从而节省大量现金和互联网地址空间。
The NAT machine has a public IP available over the internet, as well as the router and any other machines that may be available on the Internet. All of the machines inside the NAT'ed networks will be using private IP's, hence saving both a lot of cash, and the Internet address space.
我们在本章中详细解释了 NAT 及其相关理论。我们特别讨论了几个不同的使用角度,以及将 NAT 与代理一起使用时可能出现的一些常见问题。本章详细介绍了以下领域。
We have in this chapter in detail explained NAT and the theory around it. In special we have discussed a couple of different angles to use, and some of the normal problems that may arise from using NAT together with proxies. This chapter has covered the following areas in detail.
NAT使用
NAT usage
NAT组件
NAT components
NAT历史记录
NAT history
有关 NAT 的术语和用语
Terms and words used about NAT
有关 NAT 的硬件讨论
Hardware discussions regarding NAT
NAT 问题
Problems with NAT
当您使用 netfilter 和 iptables 时,所有这些都将始终有用。NAT 在当今的网络中应用非常广泛,尽管它只是一个非常不幸和意外问题的中间解决方案。当我们开始更深入地研究 Linux netfilter 和 iptables 实现时,NAT 当然会在稍后更深入地讨论。
All of this will always be of use when you are working with netfilter and iptables. NAT is very widely used in today's networks, even though it is only an intermediary solution for a very unfortunate and unexpected problem. NAT will of course be discussed more in depth later on when we start looking at the Linux netfilter and iptables implementations in more depth.
本章旨在帮助您入门并帮助您了解 Netfilter 和 iptables 在当今 Linux 中所扮演的角色。希望本章能够帮助您做好准备并完成实验以及防火墙的安装。只要有时间和毅力,您就会让它完全按照您想要的方式运行。
This chapter is aimed at getting you started and to help you understand the role Netfilter and iptables play in Linux today. This chapter should hopefully get you set up and finished to go with your experimentation, and installation of your firewall. Given time and perseverance, you'll then get it to perform exactly as you want it to.
iptables 用户空间包可以从http://www.netfilter.org/下载。iptables 包还利用了内核空间设施,可以在 make configure 期间将其配置到内核中。本文档将进一步讨论必要的步骤。
The iptables user-space package can be downloaded from the http://www.netfilter.org/. The iptables package also makes use of kernel space facilities which can be configured into the kernel during make configure. The necessary steps will be discussed a bit further down in this document.
要运行 iptables 的纯粹基础知识,您需要在执行 make config 或其相关命令之一时将以下选项配置到内核中:
To run the pure basics of iptables you need to configure the following options into the kernel while doing make config or one of its related commands:
CONFIG_PACKET - 此选项允许需要直接使用各种网络设备的应用程序和实用程序。此类实用程序的示例包括 tcpdump 或 snort。
CONFIG_PACKET - This option allows applications and utilities that need to work directly with various network devices. Examples of such utilities are tcpdump or snort.
严格来说,CONFIG_PACKET 是 iptables 工作所不需要的,但由于它包含如此多的用途,所以我选择将其包含在这里。如果您不想要它,请不要包含它。 CONFIG_PACKET is strictly speaking not needed for iptables to work, but since it contains so many uses, I have chosen to include it here. If you do not want it, don't include it. |
CONFIG_NETFILTER - 如果您要将计算机用作防火墙或 Internet 网关,则需要此选项。换句话说,这绝对是本教程中任何内容正常工作所必需的。我想您会想要这个,因为您正在阅读本文。
CONFIG_NETFILTER - This option is required if you're going to use your computer as a firewall or gateway to the Internet. In other words, this is most definitely required for anything in this tutorial to work at all. I assume you will want this, since you are reading this.
当然,您需要添加适当的驱动程序以使您的接口正常工作,例如以太网适配器、PPP 和 SLIP 接口。上面只会添加一些iptables中的纯基础知识。老实说,你将无法做任何有成效的事情,它只是将框架添加到内核中。如果您想在 Iptables 中使用更高级的选项,您需要在内核中设置正确的配置选项。在这里,我们将向您展示基本 2.4.9 内核中可用的选项并进行简要说明:
And of course you need to add the proper drivers for your interfaces to work properly, i.e. Ethernet adapter, PPP and SLIP interfaces. The above will only add some of the pure basics in iptables. You won't be able to do anything productive to be honest, it just adds the framework to the kernel. If you want to use the more advanced options in Iptables, you need to set up the proper configuration options in your kernel. Here we will show you the options available in a basic 2.4.9 kernel and a brief explanation:
CONFIG_IP_NF_CONNTRACK - 需要此模块来进行连接跟踪。连接跟踪主要由 NAT 和伪装等使用。如果您需要对 LAN 上的计算机进行防火墙,那么您绝对应该标记此选项。例如, rc.firewall.txt脚本需要此模块才能工作。
CONFIG_IP_NF_CONNTRACK - This module is needed to make connection tracking. Connection tracking is used by, among other things, NAT and Masquerading. If you need to firewall machines on a LAN you most definitely should mark this option. For example, this module is required by the rc.firewall.txt script to work.
CONFIG_IP_NF_FTP - 如果您想在 FTP 连接上进行连接跟踪,则需要此模块。由于FTP连接在正常情况下很难进行连接跟踪,因此conntrack需要一个所谓的助手;该选项编译帮助器。如果您不添加此模块,您将无法正确通过防火墙或网关进行 FTP。
CONFIG_IP_NF_FTP - This module is required if you want to do connection tracking on FTP connections. Since FTP connections are quite hard to do connection tracking on in normal cases, conntrack needs a so called helper; this option compiles the helper. If you do not add this module you won't be able to FTP through a firewall or gateway properly.
CONFIG_IP_NF_IPTABLES - 如果您想要执行任何类型的过滤、伪装或 NAT,则需要此选项。它将整个 iptables 识别框架添加到内核中。如果没有这个,你将无法使用 iptables 做任何事情。
CONFIG_IP_NF_IPTABLES - This option is required if you want do any kind of filtering, masquerading or NAT. It adds the whole iptables identification framework to the kernel. Without this you won't be able to do anything at all with iptables.
CONFIG_IP_NF_MATCH_LIMIT - 该模块并不是完全必需的,但在示例rc.firewall.txt中使用了它。此选项提供 LIMIT 匹配,这增加了控制每分钟要匹配的数据包数量的可能性,并由适当的规则控制。例如,-m limit --limit 3/分钟将每分钟最多匹配 3 个数据包。该模块还可用于避免某些拒绝服务攻击。
CONFIG_IP_NF_MATCH_LIMIT - This module isn't exactly required but it's used in the example rc.firewall.txt. This option provides the LIMIT match, that adds the possibility to control how many packets per minute that are to be matched, governed by an appropriate rule. For example, -m limit --limit 3/minute would match a maximum of 3 packets per minute. This module can also be used to avoid certain Denial of Service attacks.
CONFIG_IP_NF_MATCH_MAC - 这允许我们根据 MAC 地址匹配数据包。每个以太网适配器都有自己的 MAC 地址。例如,我们可以根据所使用的 MAC 地址来阻止数据包,并且可以很好地阻止某台计算机,因为 MAC 地址很少发生变化。我们不在rc.firewall.txt示例或其他任何地方使用此选项。
CONFIG_IP_NF_MATCH_MAC - This allows us to match packets based on MAC addresses. Every Ethernet adapter has its own MAC address. We could for instance block packets based on what MAC address is used and block a certain computer pretty well since the MAC address very seldom changes. We don't use this option in the rc.firewall.txt example or anywhere else.
CONFIG_IP_NF_MATCH_MARK - 这允许我们使用 MARK 匹配。例如,如果我们使用目标 MARK,我们可以标记一个数据包,然后根据该数据包是否在表中进一步标记,我们可以根据该标记进行匹配。这个选项就是实际的匹配MARK,下面我们将描述实际的目标MARK。
CONFIG_IP_NF_MATCH_MARK - This allows us to use a MARK match. For example, if we use the target MARK we could mark a packet and then depending on if this packet is marked further on in the table, we can match based on this mark. This option is the actual match MARK, and further down we will describe the actual target MARK.
CONFIG_IP_NF_MATCH_MULTIPORT - 该模块允许我们将数据包与整个范围的目标端口或源端口进行匹配。通常这是不可能的,但在这场比赛中却是这样。
CONFIG_IP_NF_MATCH_MULTIPORT - This module allows us to match packets with a whole range of destination ports or source ports. Normally this wouldn't be possible, but with this match it is.
CONFIG_IP_NF_MATCH_TOS - 通过此匹配,我们可以根据数据包的 TOS 字段来匹配数据包。TOS 代表服务类型。TOS 还可以通过 mangle 表中的某些规则以及通过 ip/tc 命令进行设置。
CONFIG_IP_NF_MATCH_TOS - With this match we can match packets based on their TOS field. TOS stands for Type Of Service. TOS can also be set by certain rules in the mangle table and via the ip/tc commands.
CONFIG_IP_NF_MATCH_TCPMSS - 此选项增加了我们根据 TCP 数据包的 MSS 字段匹配 TCP 数据包的可能性。
CONFIG_IP_NF_MATCH_TCPMSS - This option adds the possibility for us to match TCP packets based on their MSS field.
CONFIG_IP_NF_MATCH_STATE - 与 ipchains 相比,这是最大的新闻之一。通过这个模块,我们可以对数据包进行状态匹配。例如,如果我们已经在 TCP 连接中看到两个方向的流量,则该数据包将被计为 ESTABLISHED。该模块在rc.firewall.txt示例中广泛使用。
CONFIG_IP_NF_MATCH_STATE - This is one of the biggest news in comparison to ipchains. With this module we can do stateful matching on packets. For example, if we have already seen traffic in two directions in a TCP connection, this packet will be counted as ESTABLISHED. This module is used extensively in the rc.firewall.txt example.
CONFIG_IP_NF_MATCH_UNCLEAN - 该模块将为我们添加匹配不符合类型或无效的 IP、TCP、UDP 和 ICMP 数据包的可能性。例如,我们可以丢弃这些数据包,但我们永远不知道它们是否合法。请注意,此匹配仍处于实验阶段,可能无法在所有情况下完美运行。
CONFIG_IP_NF_MATCH_UNCLEAN - This module will add the possibility for us to match IP, TCP, UDP and ICMP packets that don't conform to type or are invalid. We could for example drop these packets, but we never know if they are legitimate or not. Note that this match is still experimental and might not work perfectly in all cases.
CONFIG_IP_NF_MATCH_OWNER - 此选项将为我们添加基于套接字所有者进行匹配的可能性。例如,我们可以只允许root用户访问Internet。该模块最初只是作为新 iptables 的功能示例而编写的。请注意,此匹配仍处于实验阶段,可能并不适合所有人。
CONFIG_IP_NF_MATCH_OWNER - This option will add the possibility for us to do matching based on the owner of a socket. For example, we can allow only the user root to have Internet access. This module was originally just written as an example on what could be done with the new iptables. Note that this match is still experimental and might not work for everyone.
CONFIG_IP_NF_FILTER - 该模块将添加基本过滤表,使您能够进行 IP 过滤。在过滤器表中,您将找到 INPUT、FORWARD 和 OUTPUT 链。如果您计划对接收和发送的数据包进行任何类型的过滤,则需要此模块。
CONFIG_IP_NF_FILTER - This module will add the basic filter table which will enable you to do IP filtering at all. In the filter table you'll find the INPUT, FORWARD and OUTPUT chains. This module is required if you plan to do any kind of filtering on packets that you receive and send.
CONFIG_IP_NF_TARGET_REJECT - 这个目标允许我们指定应该发送 ICMP 错误消息来回复传入的数据包,而不是直接将它们丢弃在地板上。请记住,与 ICMP 和 UDP 不同,TCP 连接始终通过 TCP RST 数据包重置或拒绝。
CONFIG_IP_NF_TARGET_REJECT - This target allows us to specify that an ICMP error message should be sent in reply to incoming packets, instead of plainly dropping them dead to the floor. Keep in mind that TCP connections, as opposed to ICMP and UDP, are always reset or refused with a TCP RST packet.
CONFIG_IP_NF_TARGET_MIRROR - 这允许数据包被弹回到数据包的发送者。例如,如果我们在 INPUT 链上的目标端口 HTTP 上设置一个 MIRROR 目标,并且有人尝试访问该端口,我们会将他的数据包弹回给他,最后他可能会看到自己的主页。
CONFIG_IP_NF_TARGET_MIRROR - This allows packets to be bounced back to the sender of the packet. For example, if we set up a MIRROR target on destination port HTTP on our INPUT chain and someone tries to access this port, we would bounce his packets back to him and finally he would probably see his own homepage.
MIRROR 目标不能轻易使用。它最初是作为测试和示例模块构建的,对于设置它的人来说很可能非常危险(如果除其他外,还会导致严重的 DDoS)。 The MIRROR target is not to be used lightly. It was originally built as a test and example module, and will most probably be very dangerous to the person setting it up (resulting in serious DDoS if among other things). |
CONFIG_IP_NF_NAT - 该模块允许不同形式的网络地址转换或 NAT。该选项使我们能够访问 iptables 中的 nat 表。如果我们想要进行端口转发、伪装等,则需要此选项。请注意,LAN 的防火墙和伪装不需要此选项,但除非您能够为所有主机提供唯一的 IP 地址,否则您应该将其设置为存在。因此,示例rc.firewall.txt脚本需要此选项才能正常工作,并且如果您无法添加上述指定的唯一 IP 地址,则肯定需要在您的网络上。
CONFIG_IP_NF_NAT - This module allows network address translation, or NAT, in its different forms. This option gives us access to the nat table in iptables. This option is required if we want to do port forwarding, masquerading, etc. Note that this option is not required for firewalling and masquerading of a LAN, but you should have it present unless you are able to provide unique IP addresses for all hosts. Hence, this option is required for the example rc.firewall.txt script to work properly, and most definitely on your network if you do not have the ability to add unique IP addresses as specified above.
CONFIG_IP_NF_TARGET_MASQUERADE - 该模块添加 MASQUERADE 目标。例如,如果我们不知道访问 Internet 的 IP 地址,那么这将是获取 IP 的首选方式,而不是使用 DNAT 或 SNAT。换句话说,如果我们使用 DHCP、PPP、SLIP 或其他为我们分配 IP 的连接,我们需要使用此目标而不是 SNAT。伪装给计算机带来的负载比 NAT 稍高,但无需我们提前知道 IP 地址即可工作。
CONFIG_IP_NF_TARGET_MASQUERADE - This module adds the MASQUERADE target. For instance if we don't know what IP we have to the Internet this would be the preferred way of getting the IP instead of using DNAT or SNAT. In other words, if we use DHCP, PPP, SLIP or some other connection that assigns us an IP, we need to use this target instead of SNAT. Masquerading gives a slightly higher load on the computer than NAT, but will work without us knowing the IP address in advance.
CONFIG_IP_NF_TARGET_REDIRECT - 例如,此目标与应用程序代理一起使用。我们不会让数据包直接通过,而是将它们重新映射到本地盒子。换句话说,我们有可能通过这种方式制作一个透明代理。
CONFIG_IP_NF_TARGET_REDIRECT - This target is useful together with application proxies, for example. Instead of letting a packet pass right through, we remap them to go to our local box instead. In other words, we have the possibility to make a transparent proxy this way.
CONFIG_IP_NF_TARGET_LOG - 这会将 LOG 目标及其功能添加到 iptables。我们可以使用此模块将某些数据包记录到 syslogd,从而查看数据包发生了什么。这对于安全审计、取证或调试您正在编写的脚本来说非常宝贵。
CONFIG_IP_NF_TARGET_LOG - This adds the LOG target and its functionality to iptables. We can use this module to log certain packets to syslogd and hence see what is happening to the packet. This is invaluable for security audits, forensics or debugging a script you are writing.
CONFIG_IP_NF_TARGET_TCPMSS - 此选项可用于对抗阻止 ICMP Fragmentation Needed 数据包的 Internet 服务提供商和服务器。这可能会导致网页无法通过、小邮件可以通过而较大的邮件则无法通过、ssh 可以工作但 scp 在握手后死掉等等。然后我们可以使用 TCPMSS 目标通过限制 MSS(最大分段大小)来克服这个问题)到 PMTU(路径最大传输单元)。
CONFIG_IP_NF_TARGET_TCPMSS - This option can be used to counter Internet Service Providers and servers who block ICMP Fragmentation Needed packets. This can result in web-pages not getting through, small mails getting through while larger mails don't, ssh works but scp dies after handshake, etc. We can then use the TCPMSS target to overcome this by clamping our MSS (Maximum Segment Size) to the PMTU (Path Maximum Transmit Unit).
CONFIG_IP_NF_COMPAT_IPCHAINS - 添加与过时的 ipchains 的兼容模式。不要将此视为解决从 Linux 2.2 内核迁移到 2.4 内核的任何真正的长期解决方案,因为它很可能随着内核 2.6 而消失。
CONFIG_IP_NF_COMPAT_IPCHAINS - Adds a compatibility mode with the obsolete ipchains. Do not look to this as any real long term solution for solving migration from Linux 2.2 kernels to 2.4 kernels, since it may well be gone with kernel 2.6.
CONFIG_IP_NF_COMPAT_IPFWADM - 与过时的 ipfwadm 的兼容模式。绝对不要将此视为真正的长期解决方案。
CONFIG_IP_NF_COMPAT_IPFWADM - Compatibility mode with obsolescent ipfwadm. Definitely don't look to this as a real long term solution.
正如您所看到的,有很多选项。我在这里简要解释了每个模块可以带来哪些额外行为。这些只是 vanilla Linux 2.4.9 内核中可用的选项。如果您想查看更多选项,我建议您查看 Netfilter 用户空间中的 patch-o-matic (POM) 函数,它将在内核中添加大量其他选项。POM 修复是应该在将来添加到内核中但尚未完全到达内核的附加内容。这可能有多种原因 - 例如补丁尚未稳定,Linus Torvalds 无法跟上,或者由于仍处于实验阶段而不想让补丁进入主流内核。
As you can see, there is a heap of options. I have briefly explained here what kind of extra behaviors you can expect from each module. These are only the options available in a vanilla Linux 2.4.9 kernel. If you would like to take a look at more options, I suggest you look at the patch-o-matic (POM) functions in Netfilter user-land which will add heaps of other options in the kernel. POM fixes are additions that are supposed to be added in the kernel in the future but have not quite reached the kernel yet. This may be for various reasons - such as the patch not being stable yet, to Linus Torvalds being unable to keep up, or not wanting to let the patch in to the mainstream kernel yet since it is still experimental.
您需要将以下选项编译到内核中或作为模块,以便rc.firewall.txt脚本正常工作。如果您需要其他脚本所需选项的帮助,请查看示例防火墙脚本部分。
You will need the following options compiled into your kernel, or as modules, for the rc.firewall.txt script to work. If you need help with the options that the other scripts need, look at the example firewall scripts section.
配置数据包
CONFIG_PACKET
配置网络过滤器
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_CONNTRACK
配置_IP_NF_FTP
CONFIG_IP_NF_FTP
配置_IP_NF_IRC
CONFIG_IP_NF_IRC
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_FILTER
配置_IP_NF_NAT
CONFIG_IP_NF_NAT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_TARGET_MASQUERADE
CONFIG_IP_NF_TARGET_MASQUERADE
至少rc.firewall.txt脚本需要上述内容。在其他示例脚本中,我将解释它们在各自部分中的要求。现在,让我们尝试将注意力集中在您现在应该学习的主要脚本上。
At the very least the above will be required for the rc.firewall.txt script. In the other example scripts I will explain what requirements they have in their respective sections. For now, let's try to stay focused on the main script which you should be studying now.
首先我们看一下iptables包是如何编译的。重要的是要认识到,在大多数情况下,iptables 的配置和编译与内核配置和编译是密切相关的。某些发行版预装了 iptables 软件包,其中之一是 Red Hat。然而,在旧版 Red Hat 中,它默认被禁用。我们将在本章中仔细检查如何启用它并进一步了解其他发行版。
First of all, let's look at how we compile the iptables package. It's important to realize that for the most part configuration and compilation of iptables goes hand in hand with the kernel configuration and compilation. Certain distributions come with the iptables package preinstalled, one of these is Red Hat. However, in old Red Hat it is disabled per default. We will check closer on how to enable it and take a look at other distributions further on in this chapter.
首先解压 iptables 包。在这里,我们使用了iptables 1.2.6a软件包和 vanilla 2.4 内核。像平常一样解压,使用 bzip2 -cd iptables-1.2.6a.tar.bz2 | tar -xvf - (这也可以使用 tar -xjvf iptables-1.2.6a.tar.bz2 来完成,它的作用与第一个命令几乎相同。但是,这可能不适用于旧版本的 tar)。该包现在应该正确解压到名为 iptables-1.2.6a 的目录中。有关更多信息,请阅读iptables-1.2.6a/INSTALL 文件,其中包含有关编译和运行程序的非常好的信息。
First of all unpack the iptables package. Here, we have used the iptables 1.2.6a package and a vanilla 2.4 kernel. Unpack as usual, using bzip2 -cd iptables-1.2.6a.tar.bz2 | tar -xvf - (this can also be accomplished with the tar -xjvf iptables-1.2.6a.tar.bz2, which should do pretty much the same as the first command. However, this may not work with older versions of tar). The package should now be unpacked properly into a directory named iptables-1.2.6a. For more information read the iptables-1.2.6a/INSTALL file which contains pretty good information on compiling and getting the program to run.
之后,您可以选择为内核配置和安装额外的模块和选项等。此处描述的步骤将仅检查和安装待包含到内核中的标准补丁,还有一些更多的实验性补丁,这可能仅在您执行其他步骤时可用。
After this, there you have the option of configuring and installing extra modules and options etcetera for the kernel.The step described here will only check and install standard patches that are pending for inclusion to the kernel, there are some even more experimental patches further along, which may only be available when you carry out other steps.
其中一些补丁是高度实验性的,安装它们可能不是一个好主意。然而,在这个安装步骤中有很多非常有趣的匹配和目标,所以不要害怕,至少看看它们。 Some of these patches are highly experimental and may not be such a good idea to install them. However, there are heaps of extremely interesting matches and targets in this installation step so don't be afraid of at least looking at them. 为了执行此步骤,我们从 iptables 包的根目录执行以下操作: To carry out this step we do something like this from the root of the iptables package: |
制作待处理补丁 KERNEL_DIR=/usr/src/linux/
make pending-patches KERNEL_DIR=/usr/src/linux/
该变量KERNEL_DIR应该指向内核源代码所在的实际位置。通常这应该是
/usr/src/linux/,但是这可能会有所不同,并且很可能您会知道内核源代码在哪里可用。
The variable KERNEL_DIR should point to the actual place that
your kernel source is located at. Normally this should be
/usr/src/linux/ but this may vary, and most probably you
will know yourself where the kernel source is available.
上面的命令只询问某些即将进入内核的补丁。Netfilter 的开发人员可能会向内核添加更多补丁和附加内容,但距离实际实现还有点距离。安装这些的一种方法是执行以下操作:
The above command only asks about certain patches that are just about to enter the kernel anyway. There might be more patches and additions that the developers of Netfilter are about to add to the kernel, but is a bit further away from actually getting there. One way to install these is by doing the following:
制作大部分 pom KERNEL_DIR=/usr/src/linux/
make most-of-pom KERNEL_DIR=/usr/src/linux/
上面的命令会询问安装 Netfilter 世界中称为 patch-o-matic 的部分内容,但仍然跳过可能对内核造成严重破坏的最极端的补丁。请注意,我们说“询问”,因为这就是这些命令实际执行的操作。在内核源代码发生任何更改之前,他们会询问您。为了能够安装 所有patch-o-matic 的东西,您需要运行以下命令:
The above command would ask about installing parts of what in Netfilter world is called patch-o-matic, but still skip the most extreme patches that might cause havoc in your kernel. Note that we say ask, because that's what these commands actually do. They ask you before anything is changed in the kernel source. To be able to install all of the patch-o-matic stuff you will need to run the following command:
制作 patch-o-matic KERNEL_DIR=/usr/src/linux/
make patch-o-matic KERNEL_DIR=/usr/src/linux/
在执行任何操作之前,请不要忘记彻底阅读每个补丁的帮助。有些补丁会破坏其他补丁,而另一些补丁如果与 patch-o-matic 等的某些补丁一起使用,可能会破坏您的内核。
Don't forget to read the help for each patch thoroughly before doing anything. Some patches will destroy other patches while others may destroy your kernel if used together with some patches from patch-o-matic etc.
如果您不想修补内核,您可以完全忽略上述步骤,换句话说,没有必要执行上述操作。然而,patch-o-matic 中有一些非常有趣的东西,您可能想看看,因此运行命令并查看它们包含的内容并没有什么不好。 You may totally ignore the above steps if you don't want to patch your kernel, it is in other words not necessary to do the above. However, there are some really interesting things in the patch-o-matic that you may want to look at so there's nothing bad in just running the commands and see what they contain. |
完成安装的 patch-o-matic 部分之后,您现在可以使用已添加到源中的新补丁来编译新内核。不要忘记再次配置内核,因为新补丁可能不会添加到配置的选项中。不过,如果您愿意,可以等到用户态程序 iptables 编译完成后才进行内核编译。
After this you are finished doing the patch-o-matic parts of installation, you may now compile a new kernel making use of the new patches that you have added to the source. Don't forget to configure the kernel again since the new patches probably are not added to the configured options. You may wait with the kernel compilation until after the compilation of the user-land program iptables if you feel like it, though.
继续编译 iptables 用户态应用程序。要编译 iptables,您可以发出如下所示的简单命令:
Continue by compiling the iptables user-land application. To compile iptables you issue a simple command that looks like this:
使 KERNEL_DIR=/usr/src/linux/
make KERNEL_DIR=/usr/src/linux/
用户态应用程序现在应该可以正确编译。如果没有,您就得靠自己了,或者您可以订阅Netfilter 邮件列表,在那里您有机会就您的问题寻求帮助。iptables 的安装可能会出现一些问题,所以如果它不起作用也不要惊慌。尝试逻辑思考并找出问题所在,或者请人帮助您。
The user-land application should now compile properly. If not, you are on your own, or you could subscribe to the Netfilter mailing list, where you have the chance of asking for help with your problems. There are a few things that might go wrong with the installation of iptables, so don't panic if it won't work. Try to think logically about it and find out what's wrong, or get someone to help you.
如果一切顺利,您现在就可以安装二进制文件了。为此,您需要发出以下命令来安装它们:
If everything has worked smoothly, you're ready to install the binaries by now. To do this, you would issue the following command to install them:
make install KERNEL_DIR=/usr/src/linux/
make install KERNEL_DIR=/usr/src/linux/
希望现在程序中一切都可以正常工作。要使用 iptables 用户态应用程序中的任何更改,您现在应该重新编译并重新安装内核和模块(如果您之前没有这样做)。有关从源安装用户态应用程序的更多信息,请检查源中的 INSTALL文件,其中包含有关安装主题的精彩信息。
Hopefully everything should work in the program now. To use any of the changes in the iptables user-land applications you should now recompile and reinstall your kernel and modules, if you hadn't done so before. For more information about installing the user-land applications from source, check the INSTALL file in the source which contains excellent information on the subject of installation.
Red Hat 7.1 预装了 2.4.x 内核,其中编译了 Netfilter 和 iptables。它还包含运行它所需的所有基本用户态程序和配置文件。然而,红帽人员通过使用向后兼容的 ipchains 模块禁用了整个功能。至少可以说很烦人,很多人不断询问不同的邮件列表为什么 iptables 不起作用。那么,让我们简要了解一下如何关闭 ipchains 模块以及如何安装 iptables。
Red Hat 7.1 comes preinstalled with a 2.4.x kernel that has Netfilter and iptables compiled in. It also contains all the basic user-land programs and configuration files that are needed to run it. However, the Red Hat people have disabled the whole thing by using the backward compatible ipchains module. Annoying to say the least, and a lot of people keep asking different mailing lists why iptables doesn't work. So, let's take a brief look at how to turn the ipchains module off and how to install iptables instead.
今天默认的 Red Hat 7.1 安装附带了用户空间应用程序的旧版本,因此您可能需要编译新版本的应用程序,并在完全利用 iptables 之前安装新的自定义编译内核。 The default Red Hat 7.1 installation today comes with a hopelessly old version of the user-space applications, so you might want to compile a new version of the applications as well as install a new and custom compiled kernel before fully exploiting iptables. |
首先,您需要关闭 ipchains 模块,这样它以后就不会启动。为此,您需要更改/etc/rc.d/目录结构中的一些文件名。以下命令应该可以做到这一点:
First of all you will need to turn off the ipchains modules so it won't start in the future. To do this, you will need to change some filenames in the /etc/rc.d/ directory-structure. The following command should do it:
chkconfig --level 0123456 ipchains 关闭
chkconfig --level 0123456 ipchains off
通过这样做,我们将所有指向/etc/rc.d/init.d/ipchains脚本的软链接移动 到 K92ipchains。第一个字母默认为 S,告诉 initscripts 启动脚本。通过将其更改为 K,我们告诉它终止该服务,或者如果之前未启动该服务则不运行它。现在该服务将来不会启动。
By doing this we move all the soft links that points to the /etc/rc.d/init.d/ipchains script to K92ipchains. The first letter which per default would be S, tells the initscripts to start the script. By changing this to K we tell it to Kill the service instead, or to not run it if it was not previously started. Now the service won't be started in the future.
但是,要立即停止服务的实际运行,我们需要运行另一个命令。这是可用于处理当前正在运行的服务的服务命令。然后我们将发出以下命令来停止 ipchains 服务:
However, to stop the service from actually running right now we need to run another command. This is the service command which can be used to work on currently running services. We would then issue the following command to stop the ipchains service:
服务 ipchains 停止
service ipchains stop
最后,启动iptables服务。首先,我们需要知道我们希望它运行在哪个运行级别。通常情况下,这将是运行级别 2、3 和 5。这些运行级别用于以下用途:
Finally, to start the iptables service. First of all, we need to know which run-levels we want it to run in. Normally this would be in run-level 2, 3 and 5. These run-levels are used for the following things:
2. 没有 NFS 的多用户,或者如果没有网络则与 3 相同。
2. Multiuser without NFS or the same as 3 if there is no networking.
3. 完全多用户模式,即运行的正常运行级别。
3. Full multiuser mode, i.e. the normal run-level to run in.
5.X11。如果您自动启动到 Xwindows,则使用此选项。
5. X11. This is used if you automatically boot into Xwindows.
要使 iptables 在这些运行级别中运行,我们将执行以下命令:
To make iptables run in these run-levels we would do the following commands:
chkconfig --level 235 iptables 打开
chkconfig --level 235 iptables on
换句话说,上述命令将使 iptables 服务在运行级别 2、3 和 5 中运行。如果您希望 iptables 服务在其他运行级别中运行,则必须在这些运行级别中发出相同的命令。但是,不应使用任何其他运行级别,因此您实际上不需要为这些运行级别激活它。1 级适用于单用户模式,即当您需要修理一个拧坏的盒子时。级别 4 应该未使用,级别 6 用于关闭计算机。
The above commands would in other words make the iptables service run in run-level 2, 3 and 5. If you'd like the iptables service to run in some other run-level you would have to issue the same command in those. However, none of the other run-levels should be used, so you should not really need to activate it for those run-levels. Level 1 is for single user mode, i.e, when you need to fix a screwedup box. Level 4 should be unused, and level 6 is for shutting the computer down.
要激活 iptables 服务,我们只需运行以下命令:
To activate the iptables service, we just run the following command:
服务 iptables 启动
service iptables start
iptables 脚本中没有规则。要将规则添加到 Red Hat 7.1 盒子,有两种常见的方法。首先,您可以编辑/etc/rc.d/init.d/iptables脚本。如果您通过 RPM 更新了 iptables 软件包,这会产生删除所有规则的不良效果。另一种方法是加载规则集,然后使用 iptables-save 命令保存它,然后由 rc.d 脚本自动加载。
There are no rules in the iptables script. To add rules to an Red Hat 7.1 box, there is two common ways. Firstly, you could edit the /etc/rc.d/init.d/iptables script. This would have the undesired effect of deleting all the rules if you updated the iptables package by RPM. The other way would be to load the rule-set and then save it with the iptables-save command and then have it loaded automatically by the rc.d scripts.
首先,我们将描述如何通过剪切并粘贴到 iptables init.d 脚本来设置 iptables。要添加计算机启动服务时要运行的规则,请将它们添加到 start) 部分下或 start() 函数中。请注意,如果您在 start) 部分添加规则,请不要忘记停止 start) 部分中的 start() 函数运行。另外,不要忘记编辑 stop) 部分,它告诉脚本当计算机停机时或当我们进入不需要 iptables 的运行级别时要做什么。另外,不要忘记检查重新启动部分和 condrestart。请注意,如果您有(例如,Red Hat Network)自动更新您的软件包,所有这些工作可能都会被浪费。它也可能通过从 iptables RPM 包更新而被废弃。
First we will describe the how to set up iptables by cutting and pasting to the iptables init.d script. To add rules that are to be run when the computer starts the service, you add them under the start) section, or in the start() function. Note, if you add the rules under the start) section don't forget to stop the start() function in the start) section from running. Also, don't forget to edit a the stop) section either which tells the script what to do when the computer is going down for example, or when we are entering a run-level that doesn't require iptables. Also, don't forget to check out the restart section and condrestart. Note that all this work will probably be trashed if you have, for example, Red Hat Network automatically update your packages. It may also be trashed by updating from the iptables RPM package.
第二种设置方法需要执行以下操作:首先,在 shell 脚本文件中创建并编写规则集,或者直接使用 iptables,这将满足您的要求,并且不要忘记进行一些实验。当您发现设置可以正常工作,或者您可以看到没有错误时,请使用 iptables-save 命令。您可以正常使用它,即 iptables-save > /etc/sysconfig/iptables ,这会将规则集保存到文件/etc/sysconfig/iptables中。iptables rc.d 脚本会自动使用此文件来恢复将来的规则集。另一种方法是通过执行 service iptables save 来保存脚本,这会将脚本自动保存到/etc/sysconfig/iptables。下次重新启动计算机时,iptables rc.d 脚本将使用命令 iptables-restore 从保存文件/etc/sysconfig/iptables恢复规则集。不要混合使用这两种方法,因为它们可能会严重损害彼此并使您的防火墙配置变得无用。
The second way of doing the set up would require the following: First of all, make and write a rule-set in a shell script file, or directly with iptables, that will meet your requirements, and don't forget to experiment a bit. When you find a set up that works without problems, or as you can see without bugs, use the iptables-save command. You could either use it normally, i.e. iptables-save > /etc/sysconfig/iptables, which would save the rule-set to the file /etc/sysconfig/iptables. This file is automatically used by the iptables rc.d script to restore the rule-set in the future. The other way is to save the script by doing service iptables save, which would save the script automatically to /etc/sysconfig/iptables. The next time you reboot the computer, the iptables rc.d script will use the command iptables-restore to restore the rule-set from the save-file /etc/sysconfig/iptables. Do not intermix these two methods, since they may heavily damage each other and render your firewall configuration useless.
完成所有这些步骤后,您可以卸载当前安装的 ipchains 和 iptables 软件包。这是因为我们不希望系统将新的 iptables 用户态应用程序与旧的预安装 iptables 应用程序混合在一起。仅当您要从源包安装 iptables 时才需要执行此步骤。新旧软件包混淆的情况并不罕见,因为基于 rpm 的安装将软件包安装在非标准位置,并且不会被新 iptables 软件包的安装覆盖。要执行卸载,请执行以下操作:
When all of these steps are finished, you can deinstall the currently installed ipchains and iptables packages. This because we don't want the system to mix up the new iptables user-land application with the old preinstalled iptables applications. This step is only necessary if you are going to install iptables from the source package. It's not unusual for the new and the old package to get mixed up, since the rpm based installation installs the package in non-standard places and won't get overwritten by the installation for the new iptables package. To carry out the deinstallation, do as follows:
rpm -e iptables
rpm -e iptables
如果您不再使用 ipchains,为什么还要保留它呢?删除它的方式与旧的 iptables 二进制文件等相同:
And why keep ipchains lying around if you won't be using it any more? Removing it is done the same way as with the old iptables binaries, etc:
rpm -e ipchains
rpm -e ipchains
完成所有这些后,您将按照源安装说明完成 iptables 软件包的源更新。任何旧的二进制文件、库或包含文件等都不应再存在。
After all this has been completed, you will have finished with the update of the iptables package from source, having followed the source installation instructions. None of the old binaries, libraries or include files etc should be lying around any more.
本章讨论了如何在一些常见平台上获取和安装 iptables 和 netfilter。在大多数现代 Linux 发行版中,iptables 都会默认安装,但有时可能需要编译自己的内核和 iptables 二进制文件才能获得绝对最新的更新。本章应该对管理这个问题有一点帮助。
This chapter has discussed how to get and how to install iptables and netfilter on some common platforms. In most modern Linux distributions iptables will come with the default installation, but sometimes it might be necessary to compile your own kernel and iptables binaries to get the absolutely latest updates. This chapter should have been a small help managing this.
下一章将讨论如何遍历表和链,以及遍历的顺序等等。理解这一点对于将来能够构建自己的工作规则集非常重要。所有不同的表也将进行深入讨论,因为它们是为了不同的目的而创建的。
The next chapter will discuss how tables and chains are traversed, and in what order this happens and so forth. This is very important to comprehend to be able to build your own working rulesets in the future. All the different tables will be discussed in some depth also since they are created for different purposes.
在本章中,我们将讨论数据包如何遍历不同的链以及按什么顺序。我们还将讨论遍历表的顺序。稍后,当我们编写自己的特定规则时,我们将看到这有多么有价值。我们还将研究某些其他组件(也与内核相关)进入图片的点。也就是说不同的路由决策等等。如果我们想要编写可以更改数据包的路由模式/规则的 iptables 规则,这一点尤其必要;即为什么以及如何路由数据包,DNAT 和 SNAT 就是很好的例子。当然,不要忘记 TOS 位。
In this chapter we'll discuss how packets traverse the different chains, and in which order. We will also discuss the order in which the tables are traversed. We'll see how valuable this is later on, when we write our own specific rules. We will also look at the points which certain other components, that also are kernel dependent, enter into the picture. Which is to say the different routing decisions and so on. This is especially necessary if we want to write iptables rules that could change routing patterns/rules for packets; i.e. why and how the packets get routed, good examples of this are DNAT and SNAT. Not to be forgotten are, of course, the TOS bits.
当数据包首次进入防火墙时,它会到达硬件,然后传递到内核中正确的设备驱动程序。然后,数据包开始在内核中执行一系列步骤,然后将其发送到正确的应用程序(本地),或转发到另一台主机 - 或发生任何情况。
When a packet first enters the firewall, it hits the hardware and then gets passed on to the proper device driver in the kernel. Then the packet starts to go through a series of steps in the kernel, before it is either sent to the correct application (locally), or forwarded to another host - or whatever happens to it.
首先,让我们看一下发往我们自己的本地主机的数据包。在实际交付给我们接收它的应用程序之前,它将经过以下步骤:
First, let us have a look at a packet that is destined for our own local host. It would pass through the following steps before actually being delivered to our application that receives it:
表 6-1。目标本地主机(我们自己的机器)
Table 6-1. Destination local host (our own machine)
| 步骤 | 表 | 链 | 评论 |
|---|---|---|---|
| 1 | 通过网络(例如互联网) | ||
| 2 | 来自接口(例如 eth0) | ||
| 3 | raw | PREROUTING | 该链用于在连接跟踪发生之前处理数据包。例如,它可用于设置不由连接跟踪代码处理的特定连接。 |
| 4 | 这是连接跟踪代码发生的时间,如状态机章节中所讨论的。 | ||
| 5 | mangle | PREROUTING | 该链通常用于修改数据包,即更改 TOS 等。 |
| 6 | nat | PREROUTING | 该链主要用于DNAT。避免在此链中进行过滤,因为在某些情况下它会被绕过。 |
| 7 | 路由决策,即数据包的目的地是我们本地主机还是要转发到哪里。 | ||
| 8 | mangle | INPUT | 此时,mangle INPUT 链被命中。我们使用这条链来处理数据包,在数据包被路由之后,但在它们实际发送到机器上的进程之前。 |
| 9 | filter | INPUT | 这是我们过滤发往本地主机的所有传入流量的地方。请注意,所有发往该主机的传入数据包都会通过该链,无论它们来自哪个接口或哪个方向。 |
| 10 | 本地进程或应用程序(即服务器或客户端程序)。 Local process or application (i.e., server or client program). |
请注意,这次数据包是通过 INPUT 链而不是 FORWARD 链传递的。很有逻辑。很可能一开始你眼中唯一真正符合逻辑的就是遍历表和链,但是如果你继续思考它,你会发现随着时间的推移它会变得更加清晰。
Note that this time the packet was passed through the INPUT chain instead of the FORWARD chain. Quite logical. Most probably the only thing that's really logical about the traversing of tables and chains in your eyes in the beginning, but if you continue to think about it, you'll find it will get clearer in time.
现在我们看看从我们自己的本地主机发出的数据包以及它们经历了哪些步骤。
Now we look at the outgoing packets from our own local host and what steps they go through.
表 6-2。源本地主机(我们自己的机器)
Table 6-2. Source local host (our own machine)
| 步 | 桌子 | 链 | 评论 |
|---|---|---|---|
| 1 | 本地进程/应用程序(即服务器/客户端程序) | ||
| 2 | 路由决策。使用什么源地址、使用什么传出接口以及需要收集的其他必要信息。 | ||
| 3 | raw | OUTPUT | 这是您在对本地生成的数据包进行连接跟踪之前所做的工作。例如,您可以标记连接,以便它们不会被跟踪。 |
| 4 | 这是对本地生成的数据包进行连接跟踪的地方,例如状态更改等。状态机章节对此进行了更详细的讨论。 | ||
| 5 | mangle | OUTPUT | 这是我们破坏数据包的地方,建议您不要在此链中进行过滤,因为它可能会产生副作用。 |
| 6 | nat | OUTPUT | 该链可用于对来自防火墙本身的传出数据包进行 NAT。 |
| 7 | 路由决策,因为之前的 mangle 和 nat 更改可能已经改变了数据包的路由方式。 | ||
| 8 | filter | OUTPUT | 这是我们过滤从本地主机发出的数据包的地方。 |
| 9 | mangle | POSTROUTING | mangle 表中的 POSTROUTING 链主要用于当我们想要在数据包离开主机之前、但在实际路由决策之后对其进行修改时。该链将受到刚刚穿过防火墙的数据包以及防火墙本身创建的数据包的影响。 |
| 10 | nat | POSTROUTING | 这是我们之前描述的进行 SNAT 的地方。建议您不要在此处进行过滤,因为它可能会产生副作用,并且即使您设置了默认策略 DROP,某些数据包也可能会漏掉。 |
| 11 | 在某个接口上退出(例如 eth0) | ||
| 12 | 通过网络(例如互联网) |
在此示例中,我们假设数据包的目的地是另一个网络上的另一台主机。数据包按以下方式经历不同的步骤:
In this example, we're assuming that the packet is destined for another host on another network. The packet goes through the different steps in the following fashion:
表 6-3。转发数据包
Table 6-3. Forwarded packets
| 步 | 桌子 | 链 | 评论 |
|---|---|---|---|
| 1 | 通过网络(即互联网) | ||
| 2 | 进入接口(即 eth0) | ||
| 3 | raw | PREROUTING | 您可以在此处将连接设置为不由连接跟踪系统处理。 |
| 4 | 这是非本地生成的连接跟踪发生的地方,状态机章节中也对此进行了更详细的讨论。 | ||
| 5 | mangle | PREROUTING | 该链通常用于修改数据包,即更改 TOS 等。 |
| 6 | nat | PREROUTING | 该链主要用于DNAT。SNAT 进一步完成。避免在此链中进行过滤,因为在某些情况下它会被绕过。 |
| 7 | 路由决策,即数据包的目的地是我们本地主机还是要转发到哪里。 | ||
| 8 | mangle | FORWARD | 然后数据包被发送到 mangle 表的 FORWARD 链上。这可以用于非常具体的需求,我们希望在初始路由决策之后、但在数据包发送之前做出的最后一个路由决策之前对数据包进行处理。 |
| 9 | filter | FORWARD | 数据包被路由到 FORWARD 链上。只有转发的数据包才会经过这里,我们在这里进行所有过滤。请注意,转发的所有流量都经过此处(不仅在一个方向),因此在编写规则集时需要考虑这一点。 |
| 10 | mangle | POSTROUTING | 该链用于特定类型的数据包修改,我们希望在完成各种路由决策后但仍在本机上进行这些数据包修改。 |
| 11 | nat | POSTROUTING | 该链首先应该用于 SNAT。避免在这里进行过滤,因为某些数据包可能会通过该链而不会命中它。这也是伪装的地方。 |
| 12 | 在传出接口(即 eth1)上出去。 | ||
| 13 | 再次连线(即 LAN)。 |
正如您所看到的,需要经过很多步骤。数据包可以在任何 iptables 链上停止,如果格式错误,也可以在其他任何地方停止;然而,我们主要对这个批次的 iptables 方面感兴趣。请注意,对于不同的接口或类似的东西,没有特定的链或表。通过此防火墙/路由器转发的所有数据包始终都会通过 FORWARD。
As you can see, there are quite a lot of steps to pass through. The packet can be stopped at any of the iptables chains, or anywhere else if it is malformed; however, we are mainly interested in the iptables aspect of this lot. Do note that there are no specific chains or tables for different interfaces or anything like that. FORWARD is always passed by all packets that are forwarded over this firewall/router.
在前面的场景中不要使用 INPUT 链进行过滤!INPUT 仅适用于发送至本地主机且不会路由至任何其他目的地的数据包。 Do not use the INPUT chain to filter on in the previous scenario! INPUT is meant solely for packets to our local host that do not get routed to any other destination. |
我们现在已经看到了如何在三个不同的场景中遍历不同的链。如果我们要绘制出所有这一切的一张好的地图,它看起来会像这样:
We have now seen how the different chains are traversed in three separate scenarios. If we were to figure out a good map of all this, it would look something like this:
为了澄清这个图像,请考虑这一点。如果我们将一个数据包放入第一个路由决策中,但该数据包的目的地不是本地计算机本身,它将通过 FORWARD 链进行路由。另一方面,如果数据包的目的地是本地计算机正在侦听的 IP 地址,我们将通过 INPUT 链将数据包发送到本地计算机。
To clarify this image, consider this. If we get a packet into the first routing decision that is not destined for the local machine itself, it will be routed through the FORWARD chain. If the packet is, on the other hand, destined for an IP address that the local machine is listening to, we would send the packet through the INPUT chain and to the local machine.
另外值得注意的是,数据包的目的地可能是本地计算机,但目标地址可能会通过执行 NAT 在 PREROUTING 链内更改。由于这是在第一个路由决策之前发生的,因此将在此更改之后查看数据包。因此,在路由决策完成之前,路由可能会发生变化。请注意, 所有数据包都将通过该图像中的一个或另一条路径。如果您将数据包 DNAT 回到它来自的同一网络,它仍然会穿过其余的链,直到它回到网络上。
Also worth a note, is the fact that packets may be destined for the local machine, but the destination address may be changed within the PREROUTING chain by doing NAT. Since this takes place before the first routing decision, the packet will be looked upon after this change. Because of this, the routing may be changed before the routing decision is done. Do note, that all packets will be going through one or the other path in this image. If you DNAT a packet back to the same network that it came from, it will still travel through the rest of the chains until it is back out on the network.
如果您觉得需要更多信息,可以使用rc.test-iptables.txt 脚本。该测试脚本应该为您提供必要的规则来测试如何遍历表和链。 If you feel that you want more information, you could use the rc.test-iptables.txt script. This test script should give you the necessary rules to test how the tables and chains are traversed. |
正如我们已经指出的,该表主要用于修改数据包。换句话说,您可以自由地使用该表中的 mangle 目标,更改 TOS(服务类型)字段等。
This table should as we've already noted mainly be used for mangling packets. In other words, you may freely use the mangle targets within this table, to change TOS (Type Of Service) fields and the like.
强烈建议您不要使用此表进行任何过滤;任何 DNAT、SNAT 或伪装在此表中都不起作用。 You are strongly advised not to use this table for any filtering; nor will any DNAT, SNAT or Masquerading work in this table. |
以下目标仅在 mangle 表中有效。它们不能在 mangle 表之外使用。
The following targets are only valid in the mangle table. They can not be used outside the mangle table.
服务条款
TOS
TTL
TTL
标记
MARK
塞克马克
SECMARK
康涅狄格州标志
CONNSECMARK
TOS 目标用于设置和/或更改数据包中的服务类型字段。这可用于在网络上设置有关如何路由数据包的策略等。请注意,这还没有完善,并且没有在互联网上真正实现,并且大多数路由器并不关心该字段中的值,有时,它们对所得到的内容表现出错误。换句话说,除非您想使用 iproute2 对其进行路由决策,否则不要为发送到 Internet 的数据包设置此项。
The TOS target is used to set and/or change the Type of Service field in the packet. This could be used for setting up policies on the network regarding how a packet should be routed and so on. Note that this has not been perfected and is not really implemented on the Internet and most of the routers don't care about the value in this field, and sometimes, they act faulty on what they get. Don't set this in other words for packets going to the Internet unless you want to make routing decisions on it, with iproute2.
TTL 目标用于更改数据包的 TTL(生存时间)字段。我们可以告诉数据包仅具有特定的 TTL 等等。这样做的一个很好的原因可能是我们不想把自己暴露给爱管闲事的互联网服务提供商。一些互联网服务提供商不喜欢用户在一个连接上运行多台计算机,并且已知一些互联网服务提供商会寻找生成不同 TTL 值的单个主机,并将其视为多台计算机连接到单个连接的众多标志之一。联系。
The TTL target is used to change the TTL (Time To Live) field of the packet. We could tell packets to only have a specific TTL and so on. One good reason for this could be that we don't want to give ourself away to nosy Internet Service Providers. Some Internet Service Providers do not like users running multiple computers on one single connection, and there are some Internet Service Providers known to look for a single host generating different TTL values, and take this as one of many signs of multiple computers connected to a single connection.
MARK 目标用于为数据包设置特殊标记值。然后 iproute2 程序可以识别这些标记,以便根据它们具有或不具有的标记对数据包执行不同的路由。我们还可以根据这些标记进行带宽限制和基于类的排队。
The MARK target is used to set special mark values to the packet. These marks could then be recognized by the iproute2 programs to do different routing on the packet depending on what mark they have, or if they don't have any. We could also do bandwidth limiting and Class Based Queuing based on these marks.
SECMARK 目标可用于在单个数据包上设置安全上下文标记,以便在 SELinux 和其他能够处理这些标记的安全系统中使用。然后,这用于非常细粒度的安全性,确定系统的哪些子系统可以接触哪些数据包等。SECMARK 还可以在与 CONNSECMARK 目标的整个连接上设置。
The SECMARK target can be used to set security context marks on single packets for usage in SELinux and other security systems that are able to handle these marks. This is then used for very fine grained security on what subsystems of the system can touch what packets et cetera. The SECMARK can also be set on a whole connection with the CONNSECMARK target.
CONNSECMARK 用于将安全上下文复制到整个连接的单个数据包或从整个连接的单个数据包复制安全上下文。然后,SELinux 和其他安全系统使用它在连接级别上执行更细粒度的安全性。
CONNSECMARK is used to copy a security context to or from a single packet from or to the whole connection. This is then used by the SELinux and other security systems to do more fine-grained security on a connection level.
该表只能用于不同数据包上的 NAT(网络地址转换)。换句话说,它只能用于转换数据包的源字段或目标字段。请注意,正如我们之前所说,只有流中的第一个数据包才会到达该表。此后,其余数据包将自动执行与第一个数据包相同的操作。做这些事情的实际目标是:
This table should only be used for NAT (Network Address Translation) on different packets. In other words, it should only be used to translate the packet's source field or destination field. Note that, as we have said before, only the first packet in a stream will hit this table. After this, the rest of the packets will automatically have the same action taken on them as the first packet. The actual targets that do these kind of things are:
DNAT
DNAT
网络地址转换
SNAT
假面舞会
MASQUERADE
重定向
REDIRECT
DNAT 目标主要用于您拥有公共 IP 并希望将对防火墙的访问重定向到其他主机(例如在 DMZ 上)的情况。换句话说,我们更改数据包的目标地址并将其重新路由到主机。
The DNAT target is mainly used in cases where you have a public IP and want to redirect accesses to the firewall to some other host (on a DMZ for example). In other words, we change the destination address of the packet and reroute it to the host.
SNAT主要用于改变报文的源地址。大多数情况下,您将隐藏本地网络或 DMZ 等。一个很好的例子是我们知道外部 IP 地址的防火墙,但需要用防火墙的 IP 号替换本地网络的 IP 号。通过此目标,防火墙将自动对数据包进行 SNAT 和 De-SNAT,从而可以建立从 LAN 到 Internet 的连接。例如,如果您的网络使用 192.168.0.0/netmask,则数据包将永远不会从 Internet 取回,因为 IANA 已将这些网络(以及其他网络)规定为私有网络,并且只能在隔离的 LAN 中使用。
SNAT is mainly used for changing the source address of packets. For the most part you'll hide your local networks or DMZ, etc. A very good example would be that of a firewall of which we know outside IP address, but need to substitute our local network's IP numbers with that of our firewall. With this target the firewall will automatically SNAT and De-SNAT the packets, hence making it possible to make connections from the LAN to the Internet. If your network uses 192.168.0.0/netmask for example, the packets would never get back from the Internet, because IANA has regulated these networks (among others) as private and only for use in isolated LANs.
MASQUERADE 目标的使用方式与 SNAT 完全相同,但 MASQUERADE 目标需要更多的计算开销。原因是每次 MASQUERADE 目标被数据包命中时,它都会自动检查要使用的 IP 地址,而不是像 SNAT 目标那样 - 只使用单个配置的 IP 地址。MASQUERADE 目标可以与您的 ISP 可能为您的 PPP、PPPoE 或 SLIP 连接到 Internet 的动态 DHCP IP 地址正常工作。
The MASQUERADE target is used in exactly the same way as SNAT, but the MASQUERADE target takes a little bit more overhead to compute. The reason for this, is that each time that the MASQUERADE target gets hit by a packet, it automatically checks for the IP address to use, instead of doing as the SNAT target does - just using the single configured IP address. The MASQUERADE target makes it possible to work properly with Dynamic DHCP IP addresses that your ISP might provide for your PPP, PPPoE or SLIP connections to the Internet.
原始表主要仅用于一件事,那就是在数据包上设置一个标记,表明它们不应由连接跟踪系统处理。这是通过在数据包上使用 NOTRACK 目标来完成的。如果连接被 NOTRACK 目标命中,那么 conntrack 将不会跟踪该连接。如果不添加新表,这是不可能解决的,因为只有在 conntrack 实际在数据包上运行并添加到 conntrack 表中或与已可用的连接进行匹配之后,才会调用其他表。您可以在状态机章节中阅读更多相关内容 。
The raw table is mainly only used for one thing, and that is to set a mark on packets that they should not be handled by the connection tracking system. This is done by using the NOTRACK target on the packet. If a connection is hit with the NOTRACK target, then conntrack will simply not track the connection. This has been impossible to solve without adding a new table, since none of the other tables are called until after conntrack has actually been run on the packets, and been added to the conntrack tables, or matched against an already available connection. You can read more about this in the The state machine chapter.
该表只有 PREROUTING 和 OUTPUT 链。不需要其他链,因为这些是在数据包实际到达连接跟踪之前可以处理数据包的唯一位置。
This table only has the PREROUTING and OUTPUT chains. No other chains are required since these are the only places that you can deal with packets before they actually hit the connection tracking.
为了使该表正常工作,必须加载 iptable_raw 模块。如果 iptables 使用 -t raw 关键字运行并且该模块可用,它将自动加载。 For this table to work, the iptable_raw module must be loaded. It will be loaded automatically if iptables is run with the -t raw keywords, and if the module is available. |
raw 表是 iptables 和内核中相对较新的补充。除非修补,否则它可能在早期 2.6 和 2.4 内核中不可用。 The raw table is a relatively new addition to iptables and the kernel. It might not be available in early 2.6 and 2.4 kernels unless patched. |
过滤表主要用于过滤数据包。我们可以以任何我们想要的方式匹配数据包并过滤它们。这是我们实际对数据包采取操作并查看它们包含的内容并根据其内容丢弃或/接受它们的地方。当然我们也可以做事前过滤;然而,这个特定的表是设计过滤的地方。几乎所有目标都可以在此表中使用。我们将在这里更加丰富地介绍过滤表;但是您现在知道该表是进行主要过滤的正确位置。
The filter table is mainly used for filtering packets. We can match packets and filter them in whatever way we want. This is the place that we actually take action against packets and look at what they contain and DROP or /ACCEPT them, depending on their content. Of course we may also do prior filtering; however, this particular table is the place for which filtering was designed. Almost all targets are usable in this table. We will be more prolific about the filter table here; however you now know that this table is the right place to do your main filtering.
如果数据包进入过滤表中的INPUT链等链,我们可以指定跳转规则到同一个表中的不同链。新链必须由用户指定,它可能不是内置链,例如 INPUT 或 FORWARD 链。如果我们考虑一个指向链中要执行的规则的指针,该指针将从一个规则到另一个规则,从上到下,直到链遍历由目标或主链结束(即,FORWARD,INPUT,等等)结束。一旦发生这种情况,将应用内置链的默认策略。
If a packet enters a chain such as the INPUT chain in the filter table, we can specify a jump rule to a different chain within the same table. The new chain must be userspecified, it may not be a built-in chain such as the INPUT or FORWARD chain for example. If we consider a pointer pointing at the rule in the chain to execute, the pointer will go down from rule to rule, from top to bottom until the chain traversal is either ended by a target or the main chain (I.e., FORWARD, INPUT, et cetera) ends. Once this happens, the default policy of the built-in chain will be applied.
如果匹配的规则之一指向跳转规范中的另一个用户指定的链,则指针将跳转到该链,然后开始从上到下遍历该链。例如,看看上图中规则执行如何从规则号 3 跳转到链 2。该数据包与规则 3 中包含的匹配项相匹配,并且跳转/目标规范被设置为发送该数据包以在链 2 中进行进一步检查。
If one of the rules that matches points to another userspecified chain in the jump specification, the pointer will jump over to this chain and then start traversing that chain from the top to bottom. For example, see how the rule execution jumps from rule number 3 to chain 2 in the above image. The packet matched the matches contained in rule 3, and the jump/target specification was set to send the packet on for further examination in chain 2.
用户指定的链在链的末端不能有默认策略。只有内置链才能有这个。可以通过在链末尾附加一条没有匹配项的单个规则来避免这种情况,因此它将表现为默认策略。如果用户指定的链中没有匹配规则,则默认行为是跳回原始链。如上图所示,规则执行从链 2 跳转回链 1 规则 4,位于最初将规则执行发送到链 2 的规则下方。 Userspecified chains can not have a default policy at the end of the chain. Only built in chains can have this. This can be circumvented by appending a single rule at the end of the chain that has no matches, and hence it will behave as a default policy. If no rule is matched in a userspecified chain, the default behaviour is to jump back to the originating chain. As seen in the image above, the rule execution jumps from chain 2 and back to chain 1 rule 4, below the rule that sent the rule execution into chain 2 to begin with. |
遍历用户指定的链中的每条规则,直到其中一个规则匹配为止——然后目标指定遍历应该结束还是继续——或者到达链的末尾。如果到达用户指定链的末尾,则数据包将被发送回调用链。调用链可以是用户指定的链,也可以是内置的链。
Each and every rule in the user specified chain is traversed until either one of the rules matches -- then the target specifies if the traversing should end or continue -- or the end of the chain is reached. If the end of the user specified chain is reached, the packet is sent back to the invoking chain. The invoking chain can be either a user specified chain or a built-in chain.
在本章中,我们讨论了一些链和表以及它们是如何遍历的,包括标准内置链和用户指定的链。这是一个需要理解的非常重要的领域。这可能很简单,但除非完全理解,否则同样容易犯致命错误。
In this chapter we have discussed several of the chains and tables and how they are traversed, including the standard built-in chains and userspecified chains. This is a very important area to understand. It may be simple, but unless fully understood, fatal mistakes can be equally easily.
下一章将深入讨论 netfilter 的状态机,以及如何在连接跟踪机中遍历数据包并设置状态。换句话说,下一章与本章一样重要。
The next chapter will deal in depth with the state machine of netfilter, and how states are traversed and set on packets in a connection tracking machine. The next chapter is in other words just as important as this chapter has been.
本章将讨论状态机并对其进行详细解释。读完之后,您应该对状态机的工作原理有一个完整的了解。我们还将通过大量示例来说明状态机本身如何处理状态。这些应该可以澄清实践中的一切。
This chapter will deal with the state machine and explain it in detail. After reading through it, you should have a complete understanding of how the State machine works. We will also go through a large set of examples on how states are dealt with within the state machine itself. These should clarify everything in practice.
状态机是 iptables 中的一个特殊部分,实际上根本不应该称为状态机,因为它实际上是一个连接跟踪机。然而,大多数人都通过名字认出它。在本章中,我将或多或少地使用这些名称,就好像它们是同义词一样。这不应该过于混乱。连接跟踪的目的是让 Netfilter 框架了解特定连接的状态。实现这一点的防火墙通常称为状态防火墙。状态防火墙通常比非状态防火墙安全得多,因为它允许我们编写更严格的规则集。
The state machine is a special part within iptables that should really not be called the state machine at all, since it is really a connection tracking machine. However, most people recognize it under the first name. Throughout this chapter I will use these names more or less as if they were synonymous. This should not be overly confusing. Connection tracking is done to let the Netfilter framework know the state of a specific connection. Firewalls that implement this are generally called stateful firewalls. A stateful firewall is generally much more secure than non-stateful firewalls since it allows us to write much tighter rule-sets.
在 iptables 中,数据包可以与四种不同的所谓状态下的跟踪连接相关。这些被称为新的、已建立的、相关的和无效的。稍后我们将更深入地讨论其中的每一个。通过 --state 匹配,我们可以轻松控制允许谁或什么发起新会话。
Within iptables, packets can be related to tracked connections in four different so called states. These are known as NEW, ESTABLISHED, RELATED and INVALID. We will discuss each of these in more depth later. With the --state match we can easily control who or what is allowed to initiate new sessions.
所有连接跟踪都是由内核中称为 conntrack 的特殊框架完成的。conntrack 可以作为模块加载,也可以作为内核本身的内部部分加载。大多数时候,我们需要并且想要比默认 conntrack 引擎可以维护的更具体的连接跟踪。因此,conntrack 也有更具体的部分来处理 TCP、UDP 或 ICMP 协议等。这些模块从数据包中获取特定的、唯一的信息,以便它们可以跟踪每个数据流。然后,conntrack 收集的信息用于告诉 conntrack 流当前处于哪种状态。例如,UDP 流通常由其目标 IP 地址、源 IP 地址、目标端口和源端口唯一标识。
All of the connection tracking is done by special framework within the kernel called conntrack. conntrack may be loaded either as a module, or as an internal part of the kernel itself. Most of the time, we need and want more specific connection tracking than the default conntrack engine can maintain. Because of this, there are also more specific parts of conntrack that handles the TCP, UDP or ICMP protocols among others. These modules grab specific, unique, information from the packets, so that they may keep track of each stream of data. The information that conntrack gathers is then used to tell conntrack in which state the stream is currently in. For example, UDP streams are, generally, uniquely identified by their destination IP address, source IP address, destination port and source port.
在以前的内核中,我们可以打开和关闭碎片整理。然而,自从引入了 iptables 和 Netfilter,特别是连接跟踪后,这个选项就被去掉了。原因是如果不进行数据包碎片整理,连接跟踪就无法正常工作,因此碎片整理已合并到 conntrack 中并自动执行。除非关闭连接跟踪,否则无法将其关闭。如果打开连接跟踪,则始终执行碎片整理。
In previous kernels, we had the possibility to turn on and off defragmentation. However, since iptables and Netfilter were introduced and connection tracking in particular, this option was gotten rid of. The reason for this is that connection tracking can not work properly without defragmenting packets, and hence defragmenting has been incorporated into conntrack and is carried out automatically. It can not be turned off, except by turning off connection tracking. Defragmentation is always carried out if connection tracking is turned on.
所有连接跟踪均在 PREROUTING 链中处理,本地生成的数据包除外,这些数据包在 OUTPUT 链中处理。这意味着 iptables 将在 PREROUTING 链内重新计算所有状态等。如果我们在流中发送初始数据包,则 OUTPUT 链中的状态将设置为 NEW,当我们收到返回数据包时,PREROUTING 链中的状态将更改为 ESTABLISHED,依此类推。如果第一个数据包不是我们自己发起的,当然会在 PREROUTING 链中设置 NEW 状态。因此,所有状态更改和计算都是在 nat 表的 PREROUTING 和 OUTPUT 链内完成的。
All connection tracking is handled in the PREROUTING chain, except locally generated packets which are handled in the OUTPUT chain. What this means is that iptables will do all recalculation of states and so on within the PREROUTING chain. If we send the initial packet in a stream, the state gets set to NEW within the OUTPUT chain, and when we receive a return packet, the state gets changed in the PREROUTING chain to ESTABLISHED, and so on. If the first packet is not originated by ourself, the NEW state is set within the PREROUTING chain of course. So, all state changes and calculations are done within the PREROUTING and OUTPUT chains of the nat table.
让我们简单看一下 conntrack 条目以及如何在 /proc/net/ip_conntrack中读取它们。这给出了 conntrack 数据库中所有当前条目的列表。如果加载了 ip_conntrack 模块, /proc/net/ip_conntrack的 cat可能如下所示:
Let's take a brief look at a conntrack entry and how to read them in /proc/net/ip_conntrack. This gives a list of all the current entries in your conntrack database. If you have the ip_conntrack module loaded, a cat of /proc/net/ip_conntrack might look like:
tcp 6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
dport=22 [未回复] src=192.168.1.9 dst=192.168.1.6 sport=22 \
dport=32775 [确定] use=2
tcp 6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
dport=32775 [ASSURED] use=2
此示例包含 conntrack 模块维护的所有信息,以了解特定连接处于哪种状态。首先,我们有一个协议,在本例中为 tcp。接下来,是正常十进制编码中的相同值。之后,我们看看这个 conntrack 条目必须存活多长时间。该值目前设置为 117 秒,并定期递减,直到我们看到更多流量。然后,该值将重置为其在相关时间点所处的特定状态的默认值。接下来是该条目在当前时间点所处的实际状态。在上述情况下,我们正在查看处于 SYN_SENT 状态的数据包。连接的内部值与 iptables 外部使用的值略有不同。SYN_SENT 值告诉我们,我们正在查看一个仅在一个方向上看到 TCP SYN 数据包的连接。接下来,我们看到源IP地址、目标IP地址、源端口和目标端口。此时,我们看到一个特定的关键字,它告诉我们没有看到此连接的返回流量。最后,我们看看我们对返回数据包的期望。该信息详细说明了源 IP 地址和目标 IP 地址(两者都是颠倒的,因为数据包将被定向回我们)。连接的源端口和目标端口也是如此。这些是我们应该感兴趣的价值观。此时,我们看到一个特定的关键字,它告诉我们没有看到此连接的返回流量。最后,我们看看我们对返回数据包的期望。该信息详细说明了源 IP 地址和目标 IP 地址(两者都是颠倒的,因为数据包将被定向回我们)。连接的源端口和目标端口也是如此。这些是我们应该感兴趣的价值观。此时,我们看到一个特定的关键字,它告诉我们没有看到此连接的返回流量。最后,我们看看我们对返回数据包的期望。该信息详细说明了源 IP 地址和目标 IP 地址(两者都是颠倒的,因为数据包将被定向回我们)。连接的源端口和目标端口也是如此。这些是我们应该感兴趣的价值观。
This example contains all the information that the conntrack module maintains to know which state a specific connection is in. First of all, we have a protocol, which in this case is tcp. Next, the same value in normal decimal coding. After this, we see how long this conntrack entry has to live. This value is set to 117 seconds right now and is decremented regularly until we see more traffic. This value is then reset to the default value for the specific state that it is in at that relevant point of time. Next comes the actual state that this entry is in at the present point of time. In the above mentioned case we are looking at a packet that is in the SYN_SENT state. The internal value of a connection is slightly different from the ones used externally with iptables. The value SYN_SENT tells us that we are looking at a connection that has only seen a TCP SYN packet in one direction. Next, we see the source IP address, destination IP address, source port and destination port. At this point we see a specific keyword that tells us that we have seen no return traffic for this connection. Lastly, we see what we expect of return packets. The information details the source IP address and destination IP address (which are both inverted, since the packet is to be directed back to us). The same thing goes for the source port and destination port of the connection. These are the values that should be of any interest to us.
连接跟踪条目可能采用一系列不同的值,所有这些值都在 linux/include/netfilter-ipv4/ip_conntrack*.h文件中可用的 conntrack 标头中指定。这些值取决于我们使用的 IP 子协议。TCP、UDP 或 ICMP 协议采用linux/include/netfilter-ipv4/ip_conntrack.h中指定的特定默认值 。当我们查看每个协议时,我们会更仔细地了解这一点;然而,我们不会在本章中广泛使用它们,因为它们不会在 conntrack 内部之外使用。另外,根据状态的变化,连接被破坏之前的默认时间值也会发生变化。
The connection tracking entries may take on a series of different values, all specified in the conntrack headers available in linux/include/netfilter-ipv4/ip_conntrack*.h files. These values are dependent on which sub-protocol of IP we use. TCP, UDP or ICMP protocols take specific default values as specified in linux/include/netfilter-ipv4/ip_conntrack.h. We will look closer at this when we look at each of the protocols; however, we will not use them extensively through this chapter, since they are not used outside of the conntrack internals. Also, depending on how this state changes, the default value of the time until the connection is destroyed will also change.
最近,iptables patch-o-matic 中提供了一个新补丁,称为 tcp-window-tracking。该补丁将上述所有超时添加到特殊的 sysctl 变量中,这意味着它们可以在系统仍在运行时动态更改。因此,这使得每次想要更改超时时都无需重新编译内核。 Recently there was a new patch made available in iptables patch-o-matic, called tcp-window-tracking. This patch adds, among other things, all of the above timeouts to special sysctl variables, which means that they can be changed on the fly, while the system is still running. Hence, this makes it unnecessary to recompile the kernel every time you want to change the timeouts. 这些可以通过使用/proc/sys/net/ipv4/netfilter目录中可用的特定系统调用来更改 。您应该特别查看 /proc/sys/net/ipv4/netfilter/ip_ct_*变量。 These can be altered via using specific system calls available in the /proc/sys/net/ipv4/netfilter directory. You should in particular look at the /proc/sys/net/ipv4/netfilter/ip_ct_* variables. |
当连接看到两个方向的流量时,conntrack 条目将擦除 [UNREPLIED] 标志,然后重置它。告诉我们连接没有看到任何双向流量的条目将被 [ASSURED] 标志替换,可以在条目末尾附近找到。[ASSURED] 标志告诉我们这个连接是有保证的,并且如果我们达到最大可能的跟踪连接,它不会被删除。因此,与非保证连接(未标记为 [ASSURED] 的连接)相反,标记为 [ASSURED] 的连接不会被删除。连接跟踪表可以容纳多少个连接取决于可以通过最新内核中的 ip-sysctl 函数设置的变量。该条目保存的默认值在很大程度上取决于您拥有的内存量。在 128 MB RAM 上,您将获得 8192 个可能的条目,在 256 MB RAM 上,您将获得 16376 个条目。您可以通过以下方式读取和设置您的设置 /proc/sys/net/ipv4/ip_conntrack_max设置。
When a connection has seen traffic in both directions, the conntrack entry will erase the [UNREPLIED] flag, and then reset it. The entry that tells us that the connection has not seen any traffic in both directions, will be replaced by the [ASSURED] flag, to be found close to the end of the entry. The [ASSURED] flag tells us that this connection is assured and that it will not be erased if we reach the maximum possible tracked connections. Thus, connections marked as [ASSURED] will not be erased, contrary to the non-assured connections (those not marked as [ASSURED]). How many connections that the connection tracking table can hold depends upon a variable that can be set through the ip-sysctl functions in recent kernels. The default value held by this entry varies heavily depending on how much memory you have. On 128 MB of RAM you will get 8192 possible entries, and at 256 MB of RAM, you will get 16376 entries. You can read and set your settings through the /proc/sys/net/ipv4/ip_conntrack_max setting.
另一种更有效的方法是在加载ip_conntrack模块后将 hashsize 选项设置为该模块。正常情况下ip_conntrack_max等于8 * hashsize。换句话说,将 hashsize 设置为 4096 将导致 ip_conntrack_max 设置为 32768 个 conntrack 条目。一个例子是:
A different way of doing this, that is more efficient, is to set the hashsize option to the ip_conntrack module once this is loaded. Under normal circumstances ip_conntrack_max equals 8 * hashsize. In other words, setting the hashsize to 4096 will result in ip_conntrack_max being set to 32768 conntrack entries. An example of this would be:
工作3:/home/blueflux# modprobe ip_conntrack hashsize=4096
工作3:/home/blueflux# cat /proc/sys/net/ipv4/ip_conntrack_max
32768
工作3:/home/blueflux#
work3:/home/blueflux# modprobe ip_conntrack hashsize=4096
work3:/home/blueflux# cat /proc/sys/net/ipv4/ip_conntrack_max
32768
work3:/home/blueflux#
正如您所看到的,数据包在内核本身内可能呈现几种不同的状态,具体取决于我们正在讨论的协议。然而,在内核之外,我们只有前面描述的 4 种状态。这些状态主要可以与状态匹配结合使用,然后状态匹配将能够根据数据包当前的连接跟踪状态来匹配数据包。有效状态为 NEW、ESTABLISHED、RELATED 和 INVALID。下表将简要解释每种可能的状态。
As you have seen, packets may take on several different states within the kernel itself, depending on what protocol we are talking about. However, outside the kernel, we only have the 4 states as described previously. These states can mainly be used in conjunction with the state match which will then be able to match packets based on their current connection tracking state. The valid states are NEW, ESTABLISHED, RELATED and INVALID. The following table will briefly explain each possible state.
表 7-1。用户态状态
Table 7-1. User-land states
| 状态 | 解释 |
|---|---|
| 新的 | NEW 状态告诉我们该数据包是我们看到的第一个数据包。这意味着 conntrack 模块在特定连接中看到的第一个数据包将被匹配。例如,如果我们看到一个 SYN 数据包,并且它是我们看到的连接中的第一个数据包,那么它将匹配。然而,该数据包也可能不是 SYN 数据包,并且仍然被视为新数据包。在某些情况下,这可能会导致某些问题,但当我们需要从其他防火墙恢复丢失的连接时,或者当连接已经超时但实际上并未关闭时,它也可能非常有帮助。 |
| 已确立的 | ESTABLISHED 状态已看到两个方向的流量,然后将持续匹配这些数据包。ESTABLISHED 连接相当容易理解。进入 ESTABLISHED 状态的唯一要求是一台主机发送一个数据包,然后它会收到另一台主机的回复。NEW 状态将在收到发往或通过防火墙的回复数据包后更改为 ESTABLISHED 状态。如果我们创建了一个数据包,该数据包又生成了回复 ICMP 消息,则 ICMP 回复消息也可以被视为已建立。 |
| 有关的 | RELATED 状态是比较棘手的状态之一。当一个连接与另一个已建立的连接相关时,该连接被认为是相关的。这意味着,要使连接被视为 RELATED,我们必须首先拥有一个被视为 ESTABLISHED 的连接。然后,ESTABLISHED 连接将在主连接之外生成一个连接。如果 conntrack 模块能够理解它是相关的,那么新生成的连接将被视为相关。可以被视为相关的连接的一些很好的示例是被视为与 FTP 控制端口相关的 FTP 数据连接,以及通过 IRC 发出的 DCC 连接。这可用于允许 ICMP 错误消息、FTP 传输和 DCC 通过防火墙正常工作。 |
| 无效的 | INVALID状态意味着数据包无法被识别或者没有任何状态。这可能是由于多种原因造成的,例如系统内存不足或 ICMP 错误消息不响应任何已知连接。一般来说,在这种状态下删除所有内容是个好主意。 |
| 未追踪 | 这是未跟踪状态。简而言之,如果数据包在原始表中标记为 NOTRACK 目标,则该数据包将在状态机中显示为 UNTRACKED。这也意味着所有 RELATED 连接都不会被看到,因此在处理 UNTRACKED 连接时必须小心,因为状态机将无法看到相关的 ICMP 消息等。 |
这些状态可以与 --state 匹配一起使用,以根据数据包的连接跟踪状态来匹配数据包。这就是状态机对于我们的防火墙来说如此强大和高效的原因。以前,我们经常必须打开 1024 以上的所有端口,才能让所有流量再次返回到我们的本地网络。有了状态机,就不再需要这样做了,因为我们现在只需为返回流量打开防火墙,而不是为所有其他流量打开防火墙。
These states can be used together with the --state match to match packets based on their connection tracking state. This is what makes the state machine so incredibly strong and efficient for our firewall. Previously, we often had to open up all ports above 1024 to let all traffic back into our local networks again. With the state machine in place this is not necessary any longer, since we can now just open up the firewall for return traffic and not for all kinds of other traffic.
在本节和接下来的章节中,我们将仔细研究 TCP、UDP 和 ICMP 三种基本协议的状态以及如何处理它们。此外,如果连接不能归类为这三种协议中的任何一种,我们将仔细研究默认情况下如何处理连接。我们选择从 TCP 协议开始,因为它本身就是一个有状态的协议,并且有很多关于 iptables 中的状态机的有趣细节。
In this section and the upcoming ones, we will take a closer look at the states and how they are handled for each of the three basic protocols TCP, UDP and ICMP. Also, we will take a closer look at how connections are handled per default, if they can not be classified as either of these three protocols. We have chosen to start out with the TCP protocol since it is a stateful protocol in itself, and has a lot of interesting details with regard to the state machine in iptables.
TCP 连接始终通过 3 次握手来启动,这会建立并协商发送数据的实际连接。整个会话以 SYN 数据包开始,然后是 SYN/ACK 数据包,最后是 ACK 数据包以确认整个会话的建立。此时连接已建立并可以开始发送数据。最大的问题是,连接跟踪如何与此挂钩?真的很简单。
A TCP connection is always initiated with the 3-way handshake, which establishes and negotiates the actual connection over which data will be sent. The whole session is begun with a SYN packet, then a SYN/ACK packet and finally an ACK packet to acknowledge the whole session establishment. At this point the connection is established and able to start sending data. The big problem is, how does connection tracking hook up into this? Quite simply really.
就用户而言,连接跟踪对于所有连接类型的工作原理基本相同。查看下图,了解流在连接的不同阶段进入的确切状态。正如您所看到的,从用户的角度来看,连接跟踪代码并没有真正遵循 TCP 连接的流程。一旦它看到一个数据包(SYN),它就会认为该连接是新的。一旦它看到返回数据包(SYN/ACK),它就认为连接已建立。如果你想一想,你就会明白为什么。通过这个特定的实现,您可以允许新的和已建立的数据包离开您的本地网络,只允许已建立的连接回来,这将完美地工作。相反,如果连接跟踪机将整个连接建立视为新的,我们永远无法真正阻止外部连接到我们的本地网络,因为我们必须允许新的数据包再次返回。让事情变得更复杂的是,还有许多其他内部状态用于内核内部的 TCP 连接,但在用户态中我们无法使用这些状态。大致上,它们遵循规定的国家标准RFC 793 - 传输控制协议第 21-23 页。我们将在本节中进一步详细讨论这些内容。
As far as the user is concerned, connection tracking works basically the same for all connection types. Have a look at the picture below to see exactly what state the stream enters during the different stages of the connection. As you can see, the connection tracking code does not really follow the flow of the TCP connection, from the users viewpoint. Once it has seen one packet(the SYN), it considers the connection as NEW. Once it sees the return packet(SYN/ACK), it considers the connection as ESTABLISHED. If you think about this a second, you will understand why. With this particular implementation, you can allow NEW and ESTABLISHED packets to leave your local network, only allow ESTABLISHED connections back, and that will work perfectly. Conversely, if the connection tracking machine were to consider the whole connection establishment as NEW, we would never really be able to stop outside connections to our local network, since we would have to allow NEW packets back in again. To make things more complicated, there are a number of other internal states that are used for TCP connections inside the kernel, but which are not available for us in User-land. Roughly, they follow the state standards specified within RFC 793 - Transmission Control Protocol on pages 21-23. We will consider these in more detail further along in this section.
正如您所看到的,从用户的角度来看,这确实非常简单。不过,从内核的角度来看整个构建,就有点困难了。让我们看一个例子。准确考虑/proc/net/ip_conntrack表中的连接状态如何变化 。第一个状态是在连接中收到第一个 SYN 数据包时报告的。
As you can see, it is really quite simple, seen from the user's point of view. However, looking at the whole construction from the kernel's point of view, it's a little more difficult. Let's look at an example. Consider exactly how the connection states change in the /proc/net/ip_conntrack table. The first state is reported upon receipt of the first SYN packet in a connection.
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
dport=23 [未回复] src=192.168.1.35 dst=192.168.1.5 sport=23 \
dport=1031 使用=1
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 \
dport=1031 use=1
正如您从上面的条目中看到的,我们有一个精确的状态,其中 SYN 数据包已发送(设置了 SYN_SENT 标志),并且尚未发送回复(见证 [UNREPLIED] 标志)。当我们在另一个方向看到另一个数据包时,将达到下一个内部状态。
As you can see from the above entry, we have a precise state in which a SYN packet has been sent, (the SYN_SENT flag is set), and to which as yet no reply has been sent (witness the [UNREPLIED] flag). The next internal state will be reached when we see another packet in the other direction.
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 运动=1031 \
dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
使用=1
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 \
dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
use=1
现在我们已经收到了相应的 SYN/ACK 作为回报。一旦收到此数据包,状态就会再次更改,这次更改为 SYN_RECV。SYN_RECV 告诉我们原始 SYN 已正确传送,并且 SYN/ACK 返回数据包也已正确通过防火墙。此外,该连接跟踪条目现在已看到两个方向的流量,因此被认为已得到回复。这不是明确的,而是假设的,就像上面的 [UNREPLIED] 标志一样。一旦我们看到 3 次握手中的最终 ACK,就到达了最后一步。
Now we have received a corresponding SYN/ACK in return. As soon as this packet has been received, the state changes once again, this time to SYN_RECV. SYN_RECV tells us that the original SYN was delivered correctly and that the SYN/ACK return packet also got through the firewall properly. Moreover, this connection tracking entry has now seen traffic in both directions and is hence considered as having been replied to. This is not explicit, but rather assumed, as was the [UNREPLIED] flag above. The final step will be reached once we have seen the final ACK in the 3-way handshake.
tcp 6 431999 已建立 src=192.168.1.5 dst=192.168.1.35 \
运动=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
运动=23 dport=1031 [确定] 使用=1
tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 \
sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
sport=23 dport=1031 [ASSURED] use=1
在最后一个示例中,就 iptables 的内部机制而言,我们在 3 次握手中获得了最终的 ACK,并且连接已进入 ESTABLISHED 状态。通常情况下,此时流将得到保证。
In the last example, we have gotten the final ACK in the 3-way handshake and the connection has entered the ESTABLISHED state, as far as the internal mechanisms of iptables are aware. Normally, the stream will be ASSURED by now.
连接也可能进入 ESTABLISHED 状态,但不会进入 [ASSURED]。如果我们打开了连接拾取(需要 tcp-window-tracking 补丁,并且 ip_conntrack_tcp_loose 设置为 1 或更高),就会发生这种情况。默认情况下,如果没有 tcp-window-tracking 补丁,则具有此行为,并且不可更改。
A connection may also enter the ESTABLISHED state, but not be[ASSURED]. This happens if we have connection pickup turned on (Requires the tcp-window-tracking patch, and the ip_conntrack_tcp_loose to be set to 1 or higher). The default, without the tcp-window-tracking patch, is to have this behaviour, and is not changeable.
当 TCP 连接关闭时,会按以下方式完成并采取以下状态。
When a TCP connection is closed down, it is done in the following way and takes the following states.
正如您所看到的,在发送最后一个 ACK 之前,连接永远不会真正关闭。请注意,此图仅描述了正常情况下如何关闭。例如,如果连接被拒绝,则还可以通过发送 RST(重置)来关闭连接。在这种情况下,连接将立即关闭。
As you can see, the connection is never really closed until the last ACK is sent. Do note that this picture only describes how it is closed down under normal circumstances. A connection may also, for example, be closed by sending a RST(reset), if the connection were to be refused. In this case, the connection would be closed down immediately.
当 TCP 连接关闭时,连接进入 TIME_WAIT 状态,默认设置为 2 分钟。这样一来,即使连接已经关闭,所有乱序的数据包仍然可以通过我们的规则集。这被用作一种缓冲时间,以便卡在一个或另一个拥塞路由器中的数据包仍然可以到达防火墙或连接的另一端。
When the TCP connection has been closed down, the connection enters the TIME_WAIT state, which is per default set to 2 minutes. This is used so that all packets that have gotten out of order can still get through our rule-set, even after the connection has already closed. This is used as a kind of buffer time so that packets that have gotten stuck in one or another congested router can still get to the firewall, or to the other end of the connection.
如果连接被 RST 数据包重置,则状态更改为 CLOSE。这意味着在整个连接被明确关闭之前,默认连接有 10 秒的时间。RST 数据包在任何意义上都不会被确认,并且会直接断开连接。除了我们到目前为止所介绍的状态之外,还有其他状态。以下是 TCP 流可能采取的可能状态及其超时值的完整列表。
If the connection is reset by a RST packet, the state is changed to CLOSE. This means that the connection per default has 10 seconds before the whole connection is definitely closed down. RST packets are not acknowledged in any sense, and will break the connection directly. There are also other states than the ones we have told you about so far. Here is the complete list of possible states that a TCP stream may take, and their timeout values.
表 7-2。内部状态
Table 7-2. Internal states
| 状态 | 超时值 |
|---|---|
| 没有任何 | 30分钟 |
| 已确立的 | 5天 |
| SYN_SENT | 2分钟 |
| 同步接收 | 60秒 |
| FIN_等待 | 2分钟 |
| 时间的等待 | 2分钟 |
| 关闭 | 10秒 |
| CLOSE_WAIT | 12小时 |
| 最后_ACK | 30秒 |
| 听 | 2分钟 |
这些值绝对不是绝对的。它们可能会随着内核修订而变化,也可能通过/proc/sys/net/ipv4/netfilter/ip_ct_tcp_*变量中的 proc 文件系统进行更改 。然而,默认值应该在实践中得到很好的确立。这些值以秒为单位设置。该补丁的早期版本使用 jiffies(这是一个错误)。
These values are most definitely not absolute. They may change with kernel revisions, and they may also be changed via the proc file-system in the /proc/sys/net/ipv4/netfilter/ip_ct_tcp_* variables. The default values should, however, be fairly well established in practice. These values are set in seconds. Early versions of the patch used jiffies (which was a bug).
另请注意,状态机的用户态端不会查看 TCP 数据包中设置的 TCP 标志(即 RST、ACK 和 SYN 是标志)。这通常是不好的,因为您可能希望允许处于 NEW 状态的数据包通过防火墙,但是当您指定 NEW 标志时,在大多数情况下您将意味着 SYN 数据包。 Also note that the User-land side of the state machine does not look at TCP flags (i.e., RST, ACK, and SYN are flags) set in the TCP packets. This is generally bad, since you may want to allow packets in the NEW state to get through the firewall, but when you specify the NEW flag, you will in most cases mean SYN packets. 这不是当前状态实施中发生的情况;相反,即使没有设置位或 ACK 标志的数据包也将被视为新数据包。这可以用于冗余防火墙等,但在只有一个防火墙的家庭网络上通常非常糟糕。要解决此问题,您可以使用常见问题和问题附录的“状态新数据包但没有 SYN 位设置”部分中解释的命令。另一种方法是从 patch-o-matic 安装 tcp-window-tracking 扩展,并将/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose设置 为零,这将使防火墙丢弃除SYN 标志已设置。 This is not what happens with the current state implementation; instead, even a packet with no bit set or an ACK flag, will count as NEW. This can be used for redundant firewalling and so on, but it is generally extremely bad on your home network, where you only have a single firewall. To get around this behavior, you could use the command explained in the State NEW packets but no SYN bit set section of the Common problems and questions appendix. Another way is to install the tcp-window-tracking extension from patch-o-matic, and set the /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose to zero, which will make the firewall drop all NEW packets with anything but the SYN flag set. |
UDP 连接本身不是有状态连接,而是无状态的。原因有几个,主要是因为它们不包含任何连接建立或连接关闭;最重要的是,它们缺乏排序。按特定顺序接收两个 UDP 数据报并不会说明它们的发送顺序。然而,仍然可以在内核内设置连接的状态。让我们看一下如何跟踪连接以及它在 conntrack 中的外观。
UDP connections are in themselves not stateful connections, but rather stateless. There are several reasons why, mainly because they don't contain any connection establishment or connection closing; most of all they lack sequencing. Receiving two UDP datagrams in a specific order does not say anything about the order in which they were sent. It is, however, still possible to set states on the connections within the kernel. Let's have a look at how a connection can be tracked and how it might look in conntrack.
正如您所看到的,连接的建立方式几乎与 TCP 连接完全相同。也就是说,从用户域的角度来看。从内部来看,conntrack 信息看起来有点不同,但本质上细节是相同的。首先,让我们看一下初始 UDP 数据包发送后的条目。
As you can see, the connection is brought up almost exactly in the same way as a TCP connection. That is, from the user-land point of view. Internally, conntrack information looks quite a bit different, but intrinsically the details are the same. First of all, let's have a look at the entry after the initial UDP packet has been sent.
udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
[未回复] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
dport=137 使用=1
udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
[UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
dport=137 use=1
从第一个和第二个值可以看出,这是一个 UDP 数据包。第一个是协议名称,第二个是协议编号。这与 TCP 连接相同。第三个值标记此状态条目必须存活多少秒。之后,我们获得我们所看到的数据包的值以及通过该连接从发起数据包发送者到达我们的数据包的未来期望。它们是源、目标、源端口和目标端口。此时,[UNREPLIED] 标志告诉我们到目前为止还没有对该数据包的响应。最后,我们得到了返回数据包的期望的简短列表。请注意,后面的条目与第一个值的顺序相反。默认情况下,此时超时设置为 30 秒。
As you can see from the first and second values, this is an UDP packet. The first is the protocol name, and the second is protocol number. This is just the same as for TCP connections. The third value marks how many seconds this state entry has to live. After this, we get the values of the packet that we have seen and the future expectations of packets over this connection reaching us from the initiating packet sender. These are the source, destination, source port and destination port. At this point, the [UNREPLIED] flag tells us that there's so far been no response to the packet. Finally, we get a brief list of the expectations for returning packets. Do note that the latter entries are in reverse order to the first values. The timeout at this point is set to 30 seconds, as per default.
udp 17 170 src=192.168.1.2 dst=192.168.1.5 运动=137 \
dport=1025 src=192.168.1.5 dst=192.168.1.2 运动=1025 \
dport=137 [确定] use=1
udp 17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 \
dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 \
dport=137 [ASSURED] use=1
此时,服务器已看到对发出的第一个数据包的回复,并且连接现在被视为已建立。正如您所看到的,这没有显示在连接跟踪中。主要区别在于 [UNREPLIED] 标志现已消失。此外,默认超时已更改为 180 秒 - 但在此示例中,该超时现已减少为 170 秒 - 10 秒后,它将变为 160 秒。不过,缺少一件事,并且可以稍微改变一下,那就是上面描述的 [ASSURED] 标志。为了在跟踪的连接上设置 [ASSURED] 标志,必须有一个对 NEW 数据包的合法回复数据包。
At this point the server has seen a reply to the first packet sent out and the connection is now considered as ESTABLISHED. This is not shown in the connection tracking, as you can see. The main difference is that the [UNREPLIED] flag has now gone. Moreover, the default timeout has changed to 180 seconds - but in this example that's by now been decremented to 170 seconds - in 10 seconds' time, it will be 160 seconds. There's one thing that's missing, though, and can change a bit, and that is the [ASSURED] flag described above. For the [ASSURED] flag to be set on a tracked connection, there must have been a legitimate reply packet to the NEW packet.
udp 17 175 src=192.168.1.5 dst=195.22.79.2 运动=1025 \
dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
dport=1025 [确定] use=1
udp 17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 \
dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
dport=1025 [ASSURED] use=1
至此,连接已确定。连接看起来与前面的示例完全相同。如果此连接在 180 秒内未使用,则会超时。180 秒是一个相对较低的值,但对于大多数使用来说应该足够了。对于匹配相同条目并通过防火墙的每个数据包,该值将重置为其完整值,与所有内部状态相同。
At this point, the connection has become assured. The connection looks exactly the same as the previous example. If this connection is not used for 180 seconds, it times out. 180 Seconds is a comparatively low value, but should be sufficient for most use. This value is reset to its full value for each packet that matches the same entry and passes through the firewall, just the same as for all of the internal states.
ICMP 数据包远非有状态流,因为它们仅用于控制并且永远不应该建立任何连接。然而,有四种 ICMP 类型会生成返回数据包,并且它们有 2 种不同的状态。这些 ICMP 消息可以采用 NEW 和 ESTABLISHED 状态。我们讨论的 ICMP 类型是 Echo 请求和回复、时间戳请求和回复、信息请求和回复以及最后的地址掩码请求和回复。其中,时间戳请求和信息请求已过时,很可能会被删除。但是,Echo 消息可用于多种设置,例如 ping 主机。地址掩码请求不经常使用,但有时可能很有用并且值得允许。要了解其外观,请查看下图。
ICMP packets are far from a stateful stream, since they are only used for controlling and should never establish any connections. There are four ICMP types that will generate return packets however, and these have 2 different states. These ICMP messages can take the NEW and ESTABLISHED states. The ICMP types we are talking about are Echo request and reply, Timestamp request and reply, Information request and reply and finally Address mask request and reply. Out of these, the timestamp request and information request are obsolete and could most probably just be dropped. However, the Echo messages are used in several setups such as pinging hosts. Address mask requests are not used often, but could be useful at times and worth allowing. To get an idea of how this could look, have a look at the following image.
如上图所示,主机向目标发送回显请求,防火墙将其视为 NEW。然后,目标以回显答复进行响应,防火墙将其视为状态已建立。当看到第一个 echo 请求时,以下状态条目将进入ip_conntrack。
As you can see in the above picture, the host sends an echo request to the target, which is considered as NEW by the firewall. The target then responds with a echo reply which the firewall considers as state ESTABLISHED. When the first echo request has been seen, the following state entry goes into the ip_conntrack.
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 类型=8 代码=0 \
id=33029 [未回复] src=192.168.1.10 dst=192.168.1.6 \
类型=0 代码=0 id=33029 使用=1
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
type=0 code=0 id=33029 use=1
如您所见,此条目看起来与 TCP 和 UDP 的标准状态有点不同。协议、超时以及源地址和目标地址都在那里。然而问题在那之后就来了。我们现在有 3 个新字段,称为类型、代码和 ID。它们在任何方面都没有特殊之处,类型字段包含 ICMP 类型,代码字段包含 ICMP 代码。这些都可以在ICMP 类型附录中找到。最后的 id 字段包含 ICMP ID。每个 ICMP 数据包在发送时都会设置一个 ID,当接收方收到 ICMP 消息时,它会在新的 ICMP 消息中设置相同的 ID,以便发送方能够识别回复并能够将其与发送方连接起来。正确的 ICMP 请求。
This entry looks a little bit different from the standard states for TCP and UDP as you can see. The protocol is there, and the timeout, as well as source and destination addresses. The problem comes after that however. We now have 3 new fields called type, code and id. They are not special in any way, the type field contains the ICMP type and the code field contains the ICMP code. These are all available in ICMP types appendix. The final id field, contains the ICMP ID. Each ICMP packet gets an ID set to it when it is sent, and when the receiver gets the ICMP message, it sets the same ID within the new ICMP message so that the sender will recognize the reply and will be able to connect it with the correct ICMP request.
下一个字段,我们再次识别为 [UNREPLIED] 标志,我们之前已经见过。与之前一样,此标志告诉我们当前正在查看仅在一个方向上看到流量的连接跟踪条目。最后,我们看到回复 ICMP 数据包的回复期望,它是原始源 IP 地址和目标 IP 地址的反转。至于类型和代码,这些都被更改为返回数据包的正确值,因此回显请求更改为回显应答等。ICMP ID 是从请求数据包中保留的。
The next field, we once again recognize as the [UNREPLIED] flag, which we have seen before. Just as before, this flag tells us that we are currently looking at a connection tracking entry that has seen only traffic in one direction. Finally, we see the reply expectation for the reply ICMP packet, which is the inversion of the original source and destination IP addresses. As for the type and code, these are changed to the correct values for the return packet, so an echo request is changed to echo reply and so on. The ICMP ID is preserved from the request packet.
正如我们已经解释过的,回复数据包被视为已建立。然而,我们可以肯定的是,在ICMP回复之后,同一个连接中绝对不会再有合法的流量。因此,一旦回复完全通过 Netfilter 结构,连接跟踪条目就会被销毁。
The reply packet is considered as being ESTABLISHED, as we have already explained. However, we can know for sure that after the ICMP reply, there will be absolutely no more legal traffic in the same connection. For this reason, the connection tracking entry is destroyed once the reply has traveled all the way through the Netfilter structure.
在上述每种情况下,请求都被视为 NEW,而回复则被视为 ESTABLISHED。让我们更仔细地考虑一下这一点。当防火墙看到请求数据包时,它会将其视为新数据包。当主机发送对请求的答复数据包时,它被视为已建立。
In each of the above cases, the request is considered as NEW, while the reply is considered as ESTABLISHED. Let's consider this more closely. When the firewall sees a request packet, it considers it as NEW. When the host sends a reply packet to the request it is considered ESTABLISHED.
请注意,这意味着回复数据包必须符合连接跟踪条目给出的标准才能被视为已建立,就像所有其他流量类型一样。 Note that this means that the reply packet must match the criterion given by the connection tracking entry to be considered as established, just as with all other traffic types. |
ICMP 请求的默认超时为 30 秒,您可以在 /proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout条目中更改该超时。一般来说,这应该是一个很好的超时值,因为它将能够捕获大多数传输中的数据包。
ICMP requests has a default timeout of 30 seconds, which you can change in the /proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout entry. This should in general be a good timeout value, since it will be able to catch most packets in transit.
ICMP 的另一个非常重要的部分是它用于告诉主机特定 UDP 和 TCP 连接或连接尝试发生了什么。由于这个简单的原因,ICMP 回复通常会被认为与原始连接或连接尝试相关。一个简单的示例是 ICMP 主机无法访问或 ICMP 网络无法访问。如果我们的主机尝试与其他主机建立不成功的连接,则这些应该始终生成回我们的主机,但相关网络或主机可能已关闭,因此尝试到达相关站点的最后一个路由器将回复一条 ICMP 消息,告知我们关于它。在这种情况下,ICMP 回复被视为 RELATED 数据包。下图应该解释它的外观。
Another hugely important part of ICMP is the fact that it is used to tell the hosts what happened to specific UDP and TCP connections or connection attempts. For this simple reason, ICMP replies will very often be recognized as RELATED to original connections or connection attempts. A simple example would be the ICMP Host unreachable or ICMP Network unreachable. These should always be spawned back to our host if it attempts an unsuccessful connection to some other host, but the network or host in question could be down, and hence the last router trying to reach the site in question will reply with an ICMP message telling us about it. In this case, the ICMP reply is considered as a RELATED packet. The following picture should explain how it would look.
在上面的示例中,我们向特定地址发送 SYN 数据包。防火墙将其视为新连接。然而,数据包试图到达的网络无法到达,因此路由器向我们返回网络不可达 ICMP 错误。连接跟踪代码可以将此数据包识别为“相关”。由于已经添加了跟踪条目,因此 ICMP 回复已正确发送到客户端,然后有望中止。同时,防火墙已销毁连接跟踪条目,因为它知道这是一条错误消息。
In the above example, we send out a SYN packet to a specific address. This is considered as a NEW connection by the firewall. However, the network the packet is trying to reach is unreachable, so a router returns a network unreachable ICMP error to us. The connection tracking code can recognize this packet as RELATED. thanks to the already added tracking entry, so the ICMP reply is correctly sent to the client which will then hopefully abort. Meanwhile, the firewall has destroyed the connection tracking entry since it knows this was an error message.
如果 UDP 连接遇到上述任何问题,则会出现与上述相同的行为。所有为回复 UDP 连接而发送的 ICMP 消息都被视为相关的。考虑下图。
The same behavior as above is experienced with UDP connections if they run into any problem like the above. All ICMP messages sent in reply to UDP connections are considered as RELATED. Consider the following image.
这次UDP数据包被发送到主机。该 UDP 连接被视为新连接。然而,网络在传输过程中被某些防火墙或路由器在管理上禁止。因此,我们的防火墙会收到 ICMP 网络禁止作为回报。防火墙知道此 ICMP 错误消息与已打开的 UDP 连接相关,并将其作为 RELATED 数据包发送到客户端。此时,防火墙会破坏连接跟踪条目,客户端收到 ICMP 消息,应该会中止。
This time an UDP packet is sent to the host. This UDP connection is considered as NEW. However, the network is administratively prohibited by some firewall or router on the way over. Hence, our firewall receives a ICMP Network Prohibited in return. The firewall knows that this ICMP error message is related to the already opened UDP connection and sends it as a RELATED packet to the client. At this point, the firewall destroys the connection tracking entry, and the client receives the ICMP message and should hopefully abort.
在某些情况下,conntrack 机器不知道如何处理特定协议。如果它不了解该协议,或者不知道它是如何工作的,就会发生这种情况。在这些情况下,它会返回到默认行为。默认行为用于 NETBLT、MUX 和 EGP 等。此行为看起来与 UDP 连接跟踪非常相似。第一个数据包被视为“新”,而回复流量等被视为“已建立”。
In certain cases, the conntrack machine does not know how to handle a specific protocol. This happens if it does not know about that protocol in particular, or doesn't know how it works. In these cases, it goes back to a default behavior. The default behavior is used on, for example, NETBLT, MUX and EGP. This behavior looks pretty much the same as the UDP connection tracking. The first packet is considered NEW, and reply traffic and so forth is considered ESTABLISHED.
当使用默认行为时,所有这些数据包将获得相同的默认超时值。这可以通过/proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout变量设置 。此处的默认值为 600 秒,即 10 分钟。根据您尝试通过使用默认连接跟踪行为的链接发送的流量,这可能需要更改。特别是如果您通过卫星等来传输流量,这可能需要很长时间。
When the default behavior is used, all of these packets will attain the same default timeout value. This can be set via the /proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout variable. The default value here is 600 seconds, or 10 minutes. Depending on what traffic you are trying to send over a link that uses the default connection tracking behavior, this might need changing. Especially if you are bouncing traffic through satellites and such, which can take a long time.
当涉及到 Linux 中的连接跟踪时,UNTRACKED 是一个相当特殊的关键字。基本上,它用于匹配原始表中已标记为不被跟踪的数据包。
UNTRACKED is a rather special keyword when it comes to connection tracking in Linux. Basically, it is used to match packets that has been marked in the raw table not to be tracked.
原始表是专门为此创建的。在此表中,您可以在不希望在 netfilter 中跟踪的数据包上设置 NOTRACK 标记。
The raw table was created specifically for this reason. In this table, you set a NOTRACK mark on packets that you do not wish to track in netfilter.
请注意我如何说数据包,而不是连接,因为标记实际上是为每个进入的数据包设置的。否则,我们仍然需要对连接进行某种类型的跟踪才能知道它不应该被跟踪。 Notice how I say packets, not connection, since the mark is actually set for each and every packet that enters. Otherwise, we would still have to do some kind of tracking of the connection to know that it should not be tracked. |
正如我们在本章中已经说过的,conntrack 和状态机相当消耗资源。因此,有时关闭连接跟踪和状态机可能是个好主意。
As we have already stated in this chapter, conntrack and the state machine is rather resource hungry. For this reason, it might sometimes be a good idea to turn off connection tracking and the state machine.
一个例子是,如果您有一台流量很大的路由器,您希望在其上对传入和传出流量进行防火墙设置,但不对路由流量进行防火墙设置。然后,您可以通过在原始表中接受所有以您的主机为目的地的数据包,在所有未发往防火墙本身的数据包上设置 NOTRACK 标记,然后为所有其他流量设置 NOTRACK。这将允许您对路由器本身的传入流量进行状态匹配,但同时由于不处理所有交叉流量而节省了处理能力。
One example would be if you have a heavily trafficked router that you want to firewall the incoming and outgoing traffic on, but not the routed traffic. You could then set the NOTRACK mark on all packets not destined for the firewall itself by ACCEPT'ing all packets with destination your host in the raw table, and then set the NOTRACK for all other traffic. This would then allow you to have stateful matching on incoming traffic for the router itself, but at the same time save processing power from not handling all the crossing traffic.
可以使用 NOTRACK 的另一个例子是,如果您有一个流量很大的网络服务器,并且想要进行状态跟踪,但又不想在跟踪网络流量上浪费处理能力。然后,您可以设置一条规则,对所有本地拥有的 IP 地址或实际提供 Web 流量的 IP 地址上的端口 80 进行跟踪。然后,您可以享受对所有其他服务的全状态跟踪,但网络流量除外,这可能会在已经过载的系统上节省一些处理能力。
Another example when NOTRACK can be used is if you have a highly trafficked webserver and want to do stateful tracking, but don't want to waste processing power on tracking the web traffic. You could then set up a rule that turns of tracking for port 80 on all the locally owned IP addresses, or the ones that are actually serving web traffic. You could then enjoy statefull tracking on all other services, except for webtraffic which might save some processing power on an already overloaded system.
然而,NOTRACK 存在一些您必须考虑的问题。如果使用 NOTRACK 设置整个连接,那么您也将无法跟踪相关连接,conntrack 和 nat 帮助程序将无法用于未跟踪的连接,相关的 ICMP 错误也不起作用。换句话说,您必须手动打开这些。当涉及 FTP 和 SCTP 等复杂协议时,这可能很难管理。只要您意识到这一点,您就应该能够处理这个问题。
There is however some problems with NOTRACK that you must take into consideration. If a whole connection is set with NOTRACK, then you will not be able to track related connections either, conntrack and nat helpers will simply not work for untracked connections, nor will related ICMP errors do. You will have to open up for these manually in other words. When it comes to complex protocols such as FTP and SCTP et cetera, this can be very hard to manage. As long as you are aware of this, you should be able to handle this however.
某些协议比其他协议更复杂。当涉及到连接跟踪时,这意味着此类协议可能更难正确跟踪。ICQ、IRC 和 FTP 协议就是很好的例子。这些协议中的每一种都在数据包的实际数据有效负载中携带信息,因此需要特殊的连接跟踪帮助程序才能使其正常运行。
Certain protocols are more complex than others. What this means when it comes to connection tracking, is that such protocols may be harder to track correctly. Good examples of these are the ICQ, IRC and FTP protocols. Each and every one of these protocols carries information within the actual data payload of the packets, and hence requires special connection tracking helpers to enable it to function correctly.
这是 Linux 内核内部支持的复杂协议的列表,以及它是在哪个内核版本中引入的。
This is a list of the complex protocols that has support inside the linux kernel, and which kernel version it was introduced in.
文件传输协议
FTP
IRC
IRC
TFTP
TFTP
我们以 FTP 协议作为第一个例子。FTP 协议首先打开一个称为 FTP 控制会话的连接。当我们通过此会话发出命令时,其他端口将打开以携带与该特定命令相关的其余数据。这些连接可以通过主动或被动两种方式完成。当主动建立连接时,FTP 客户端会向服务器发送要连接的端口和 IP 地址。此后,FTP 客户端打开端口,服务器从随机非特权端口 (>1024) 连接到该指定端口,并通过该端口发送数据。
Let's take the FTP protocol as the first example. The FTP protocol first opens up a single connection that is called the FTP control session. When we issue commands through this session, other ports are opened to carry the rest of the data related to that specific command. These connections can be done in two ways, either actively or passively. When a connection is done actively, the FTP client sends the server a port and IP address to connect to. After this, the FTP client opens up the port and the server connects to that specified port from a random unprivileged port (>1024) and sends the data over it.
这里的问题是防火墙不会知道这些额外的连接,因为它们是在协议数据的实际有效负载内协商的。因此,防火墙将无法知道它应该让服务器通过这些特定端口连接到客户端。
The problem here is that the firewall will not know about these extra connections, since they were negotiated within the actual payload of the protocol data. Because of this, the firewall will be unable to know that it should let the server connect to the client over these specific ports.
解决这个问题的方法是在连接跟踪模块中添加一个特殊的帮助程序,该模块将扫描控制连接中的数据以获取特定的语法和信息。当它遇到正确的信息时,它会将该特定信息添加为“相关”,并且由于该“相关”条目,服务器将能够跟踪连接。请考虑下图以了解 FTP 服务器与客户端建立连接时的状态。
The solution to this problem is to add a special helper to the connection tracking module which will scan through the data in the control connection for specific syntaxes and information. When it runs into the correct information, it will add that specific information as RELATED and the server will be able to track the connection, thanks to that RELATED entry. Consider the following picture to understand the states when the FTP server has made the connection back to the client.
被动 FTP 的工作方式相反。FTP 客户端告诉服务器它需要一些特定数据,服务器会回复要连接的 IP 地址和端口。客户端收到此数据后,将从其自己的端口 20(FTP 数据端口)连接到该特定端口,并获取相关数据。如果您的防火墙后面有一个 FTP 服务器,换句话说,除了标准 iptables 模块之外,您还需要此模块,以便 Internet 上的客户端正确连接到 FTP 服务器。如果您对用户的限制非常严格,并且只想让他们访问 Internet 上的 HTTP 和 FTP 服务器并阻止所有其他端口,情况也是如此。考虑下图及其对被动 FTP 的影响。
Passive FTP works the opposite way. The FTP client tells the server that it wants some specific data, upon which the server replies with an IP address to connect to and at what port. The client will, upon receipt of this data, connect to that specific port, from its own port 20(the FTP-data port), and get the data in question. If you have an FTP server behind your firewall, you will in other words require this module in addition to your standard iptables modules to let clients on the Internet connect to the FTP server properly. The same goes if you are extremely restrictive to your users, and only want to let them reach HTTP and FTP servers on the Internet and block all other ports. Consider the following image and its bearing on Passive FTP.
一些 conntrack 助手已经在内核本身中可用。更具体地说,在撰写本文时,FTP 和 IRC 协议已经有 conntrack 帮助程序。如果您在内核本身中找不到所需的 conntrack 帮助程序,则应该查看用户态 iptables 中的 patch-o-matic 树。patch-o-matic 树可能包含更多 conntrack 助手,例如 ntalk 或 H.323 协议。如果它们在 patch-o-matic 树中不可用,您有多种选择。您可以查看 iptables 的 CVS 源(如果它最近已进入该树),或者您可以联系Netfilter-devel 邮件列表并询问它是否可用。如果不是,并且没有添加它的计划,那么您只能使用自己的设备,并且很可能想要阅读Rusty Russell 的《不可靠的 Netfilter 黑客攻击方法》可从其他资源和链接附录链接 。
Some conntrack helpers are already available within the kernel itself. More specifically, the FTP and IRC protocols have conntrack helpers as of writing this. If you can not find the conntrack helpers that you need within the kernel itself, you should have a look at the patch-o-matic tree within user-land iptables. The patch-o-matic tree may contain more conntrack helpers, such as for the ntalk or H.323 protocols. If they are not available in the patch-o-matic tree, you have a number of options. Either you can look at the CVS source of iptables, if it has recently gone into that tree, or you can contact the Netfilter-devel mailing list and ask if it is available. If it is not, and there are no plans for adding it, you are left to your own devices and would most probably want to read the Rusty Russell's Unreliable Netfilter Hacking HOW-TO which is linked from the Other resources and links appendix.
Conntrack 帮助程序可以静态编译到内核中,也可以作为模块编译。如果它们被编译为模块,您可以使用以下命令加载它们
Conntrack helpers may either be statically compiled into the kernel, or as modules. If they are compiled as modules, you can load them with the following command
modprobe ip_conntrack_ftp modprobe ip_conntrack_irc modprobe ip_conntrack_tftp modprobe ip_conntrack_amanda
modprobe ip_conntrack_ftp modprobe ip_conntrack_irc modprobe ip_conntrack_tftp modprobe ip_conntrack_amanda
请注意,连接跟踪与 NAT 无关,因此如果您也对连接进行 NAT,则可能需要更多模块。例如,如果您想要进行 NAT 并跟踪 FTP 连接,则还需要 NAT 模块。所有 NAT 助手均以 ip_nat_ 开头并遵循该命名约定;例如,FTP NAT 帮助程序将被命名为 ip_nat_ftp,IRC 模块将被命名为 ip_nat_irc。conntrack 帮助程序遵循相同的命名约定,因此 IRC conntrack 帮助程序将命名为 ip_conntrack_irc,而 FTP conntrack 帮助程序将命名为 ip_conntrack_ftp。
Do note that connection tracking has nothing to do with NAT, and hence you may require more modules if you are NAT'ing connections as well. For example, if you were to want to NAT and track FTP connections, you would need the NAT module as well. All NAT helpers starts with ip_nat_ and follow that naming convention; so for example the FTP NAT helper would be named ip_nat_ftp and the IRC module would be named ip_nat_irc. The conntrack helpers follow the same naming convention, and hence the IRC conntrack helper would be named ip_conntrack_irc, while the FTP conntrack helper would be named ip_conntrack_ftp.
本章讨论了 netfilter 中的状态机如何工作以及它如何保持不同连接的状态。本章还讨论了它如何向您(最终用户)表示,以及您可以采取哪些措施来改变其行为,以及进行连接跟踪更复杂的不同协议,以及不同的 conntrack 帮助程序如何发挥作用。
This chapter has discussed how the state machine in netfilter works and how it keeps state of different connections. The chapter has also discussed how it is represented toward you, the end user and what you can do to alter its behavior, as well as different protocols that are more complex to do connection tracking on, and how the different conntrack helpers come into the picture.
下一章将讨论如何使用 iptables 应用程序分发的 iptables-save 和 iptables-restore 程序来保存和恢复规则集。这有利有弊,本章将详细讨论。
The next chapter will discuss how to save and restore rulesets using the iptables-save and iptables-restore programs distributed with the iptables applications. This has both pros and cons, and the chapter will discuss it in detail.
iptables 软件包附带了另外两个非常有用的工具,特别是当您正在处理更大的规则集时。这两个工具称为 iptables-save 和 iptables-restore,用于将规则集保存和恢复为特定的文件格式,该文件格式与您将在本教程的其余部分中看到的标准 shell 代码有很大不同。
The iptables package comes with two more tools that are very useful, specially if you are dealing with larger rule-sets. These two tools are called iptables-save and iptables-restore and are used to save and restore rule-sets to a specific file-format that looks quite a bit different from the standard shell code that you will see in the rest of this tutorial.
iptables-restore 可以与脚本语言一起使用。最大的问题是您需要将结果输出到 iptables-restore 的标准输入中。如果您正在创建一个非常大的规则集(数千条规则),这可能是一个非常好的主意,因为插入所有新规则会更快。例如,您可以运行 make_rules.sh | iptables-恢复。 iptables-restore can be used together with scripting languages. The big problem is that you will need to output the results into the stdin of iptables-restore. If you are creating a very big ruleset (several thousand rules) this might be a very good idea, since it will be much faster to insert all the new rules. For example, you would then run make_rules.sh | iptables-restore. |
使用 iptables-save 和 iptables-restore 命令的最大原因之一是它们将大大加快较大规则集的加载和保存速度。运行包含 iptables 规则的 shell 脚本的主要问题是,脚本中每次调用 iptables 都会首先从 Netfilter 内核空间中提取整个规则集,然后,它将插入或附加规则,或者执行任何更改此特定命令所需的规则集。最后,它会将新的规则集从自己的内存插入到内核空间。使用 shell 脚本,可以为我们想要插入的每条规则完成此操作,并且每次执行此操作时,都需要更多时间来提取和插入规则集。
One of the largest reasons for using the iptables-save and iptables-restore commands is that they will speed up the loading and saving of larger rule-sets considerably. The main problem with running a shell script that contains iptables rules is that each invocation of iptables within the script will first extract the whole rule-set from the Netfilter kernel space, and after this, it will insert or append rules, or do whatever change to the rule-set that is needed by this specific command. Finally, it will insert the new rule-set from its own memory into kernel space. Using a shell script, this is done for each and every rule that we want to insert, and for each time we do this, it takes more time to extract and insert the rule-set.
为了解决这个问题,有iptables-save和restore命令。iptables-save 命令用于将规则集保存到特殊格式的文本文件中,iptables-restore 命令用于将该文本文件再次加载到内核中。这些命令最好的部分是它们将在一个请求中加载和保存规则集。iptables-save 将从内核获取整个规则集并将其保存到一个文件中。iptables-restore 会在每个表的单个移动中将该特定规则集上传到内核。换句话说,对于非常大的规则集,不是将规则集从内核中删除大约 30,000 次,然后再次将其上传到内核那么多次,
To solve this problem, there is the iptables-save and restore commands. The iptables-save command is used to save the rule-set into a specially formatted text-file, and the iptables-restore command is used to load this text-file into kernel again. The best parts of these commands is that they will load and save the rule-set in one single request. iptables-save will grab the whole rule-set from kernel and save it to a file in one single movement. iptables-restore will upload that specific rule-set to kernel in a single movement for each table. In other words, instead of dropping the rule-set out of kernel some 30,000 times, for really large rule-sets, and then upload it to kernel again that many times, we can now save the whole thing into a file in one movement and then upload the whole thing in as little as three movements depending on how many tables you use.
正如您所理解的,如果您正在处理大量需要插入的规则,那么这些工具绝对适合您。然而,它们确实有缺点,我们将在下一节中详细讨论。
As you can understand, these tools are definitely something for you if you are working on a huge set of rules that needs to be inserted. However, they do have drawbacks that we will discuss more in the next section.
您可能已经想知道,iptables-restore 可以处理任何类型的脚本吗?到目前为止,不,它不能,而且很可能永远不能。这是使用 iptables-restore 的主要缺陷,因为您将无法使用这些文件执行大量操作。例如,如果您的连接具有动态分配的 IP 地址,并且您希望在每次计算机启动时获取此动态 IP,然后在脚本中使用该值,该怎么办?使用 iptables-restore,这或多或少是不可能的。
As you may have already wondered, can iptables-restore handle any kind of scripting? So far, no, it cannot and it will most probably never be able to. This is the main flaw in using iptables-restore since you will not be able to do a huge set of things with these files. For example, what if you have a connection that has a dynamically assigned IP address and you want to grab this dynamic IP every-time the computer boots up and then use that value within your scripts? With iptables-restore, this is more or less impossible.
解决这个问题的一种可能性是制作一个小脚本,获取您想要在脚本中使用的值,然后使用 sed iptables-restore 文件查找特定关键字,并将它们替换为通过小脚本收集的值。此时,您可以将其保存到临时文件,然后使用 iptables-restore 加载新值。然而,这会导致很多问题,并且您将无法正确使用 iptables-save,因为它可能会删除您在恢复脚本中手动添加的关键字。换句话说,这是一个笨拙的解决方案。
One possibility to get around this is to make a small script which grabs the values you would like to use in the script, then sed the iptables-restore file for specific keywords and replace them with the values collected via the small script. At this point, you could save it to a temporary file, and then use iptables-restore to load the new values. This causes a lot of problems however, and you will be unable to use iptables-save properly since it would probably erase your manually added keywords in the restore script. It is, in other words, a clumsy solution.
第二种可能性是按照前面描述的那样进行。制作一个以 iptables-restore 格式输出规则的脚本,然后将它们提供给 iptables-restore 的标准输入。对于非常大的规则集,这比运行 iptables 本身更好,因为它有一个坏习惯,即在非常大的规则集上占用大量处理能力,如本章前面所述。
A second possibility is to do as previously described. Make a script that outputs rules in iptables-restore format, and then feed them on standard input of iptables-restore. For very large rulesets this would be to be preferred over running iptables itself, since it has a bad habit of taking a lot of processing power on very large rulesets as previously described in this chapter.
另一种解决方案是首先加载 iptables-restore 脚本,然后加载特定的 shell 脚本,该脚本在适当的位置插入更多动态规则。当然,正如您所理解的,这与第一个解决方案一样笨拙。iptables-restore 不太适合将 IP 地址动态分配给防火墙的配置,或者您希望根据配置选项采取不同行为的配置等。
Another solution is to load the iptables-restore scripts first, and then load a specific shell script that inserts more dynamic rules in their proper places. Of course, as you can understand, this is just as clumsy as the first solution. iptables-restore is simply not very well suited for configurations where IP addresses are dynamically assigned to your firewall or where you want different behaviors depending on configuration options and so on.
iptables-restore 和 iptables-save 的另一个缺点是,在编写本文时它还没有完全发挥作用。问题很简单,到目前为止,没有很多人使用它,因此没有很多人发现错误,反过来,一些匹配和目标将简单地插入错误,这可能会导致你所做的一些奇怪的行为没想到。尽管存在这些问题,我还是强烈建议使用这些工具,只要它们不包含一些不知道如何正确处理的新目标或匹配项,它们对于大多数规则集都应该非常有效。
Another drawback with iptables-restore and iptables-save is that it is not fully functional as of writing this. The problem is simply that not a lot of people use it as of today and hence there are not a lot of people finding bugs, and in turn some matches and targets will simply be inserted badly, which may lead to some strange behaviors that you did not expect. Even though these problems exist, I would highly recommend using these tools which should work extremely well for most rule-sets as long as they do not contain some of the new targets or matches that it does not know how to handle properly.
正如我们已经解释过的,iptables-save 命令是一个将当前规则集保存到 iptables-restore 可以使用的文件中的工具。这个命令确实非常简单,只需要两个参数。查看以下示例以了解该命令的语法。
The iptables-save command is, as we have already explained, a tool to save the current rule-set into a file that iptables-restore can use. This command is quite simple really, and takes only two arguments. Take a look at the following example to understand the syntax of the command.
iptables-save [-c] [-t表]
iptables-save [-c] [-t table]
-c 参数告诉 iptables-save 保留字节和数据包计数器中指定的值。例如,如果我们想重新启动主防火墙,但又不想丢失可用于统计目的的字节和数据包计数器,则这可能很有用。发出带有 -c 参数的 iptables-save 命令将使我们能够在不破坏统计和会计例程的情况下重新启动。当然,默认值是在发出此命令时不保持计数器完整。
The -c argument tells iptables-save to keep the values specified in the byte and packet counters. This could for example be useful if we would like to reboot our main firewall, but not lose byte and packet counters which we may use for statistical purposes. Issuing a iptables-save command with the -c argument would then make it possible for us to reboot without breaking our statistical and accounting routines. The default value is, of course, to not keep the counters intact when issuing this command.
-t 参数告诉 iptables-save 命令要保存哪些表。如果没有此参数,该命令将自动将所有可用表保存到文件中。以下示例说明了在未加载任何规则集的情况下 iptables-save 命令会出现什么输出。
The -t argument tells the iptables-save command which tables to save. Without this argument the command will automatically save all tables available into the file. The following is an example on what output you can expect from the iptables-save command if you do not have any rule-set loaded.
# 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:17 生成 *筛选 :输入接受[404:19766] :转发接受[0:0] :输出接受 [530:43376] 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:17 完成 # 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:17 生成 *损坏 :PREROUTING接受[451:22060] :输入接受[451:22060] :转发接受[0:0] :输出接受 [594:47151] : 后路由接受 [594:47151] 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:17 完成 # 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:17 生成 *nat :PREROUTING接受[0:0] :后路由接受 [3:450] :输出接受 [3:450] 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:17 完成
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002 *filter :INPUT ACCEPT [404:19766] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [530:43376] COMMIT # Completed on Wed Apr 24 10:19:17 2002 # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002 *mangle :PREROUTING ACCEPT [451:22060] :INPUT ACCEPT [451:22060] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [594:47151] :POSTROUTING ACCEPT [594:47151] COMMIT # Completed on Wed Apr 24 10:19:17 2002 # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002 *nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [3:450] :OUTPUT ACCEPT [3:450] COMMIT # Completed on Wed Apr 24 10:19:17 2002
其中包含一些以 # 符号开头的注释。每个表都标记为 *<table-name>,例如 *mangle。然后在每个表中我们都有链规范和规则。链规范类似于:<chain-name> <chain-policy> [<packet-counter>:<byte-counter>]。链名称可以是例如 PREROUTING,策略之前已描述并且可以是例如 ACCEPT。最后,数据包计数器和字节计数器与 iptables -L -v 的输出中的计数器相同。最后,每个表声明以 COMMIT 关键字结束。COMMIT 关键字告诉我们,此时我们应该将管道中当前的所有规则提交到内核。
This contains a few comments starting with a # sign. Each table is marked like *<table-name>, for example *mangle. Then within each table we have the chain specifications and rules. A chain specification looks like :<chain-name> <chain-policy> [<packet-counter>:<byte-counter>]. The chain-name may be for example PREROUTING, the policy is described previously and can, for example, be ACCEPT. Finally the packet-counter and byte-counters are the same counters as in the output from iptables -L -v. Finally, each table declaration ends in a COMMIT keyword. The COMMIT keyword tells us that at this point we should commit all rules currently in the pipeline to kernel.
上面的示例非常基本,因此我认为展示一个包含非常小的Iptables-save 规则集的简短示例是正确的。如果我们对此运行 iptables-save,输出将如下所示:
The above example is pretty basic, and hence I believe it is nothing more than proper to show a brief example which contains a very small Iptables-save ruleset. If we would run iptables-save on this, it would look something like this in the output:
# 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:55 生成 *筛选 :输入下降 [1:229] : 向前下降 [0:0] :输出下降[0:0] -A 输入 -m 状态 --state 相关,已建立 -j 接受 -A FORWARD -i eth0 -m state --state 相关,已建立 -j 接受 -A FORWARD -i eth1 -m state --state 新的、相关的、已建立的 -j 接受 -A 输出 -m 状态 --state 新的、相关的、已建立的 -j 接受 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:55 完成 # 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:55 生成 *损坏 :PREROUTING接受 [658:32445] :输入接受[658:32445] :转发接受[0:0] :输出接受 [891:68234] : 后路由接受 [891:68234] 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:55 完成 # 由 iptables-save v1.2.6a 于 2002 年 4 月 24 日星期三 10:19:55 生成 *nat :PREROUTING接受 [1:229] :后路由接受 [3:450] :输出接受 [3:450] -A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1 犯罪 # 于 2002 年 4 月 24 日星期三 10:19:55 完成
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002 *filter :INPUT DROP [1:229] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT COMMIT # Completed on Wed Apr 24 10:19:55 2002 # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002 *mangle :PREROUTING ACCEPT [658:32445] :INPUT ACCEPT [658:32445] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [891:68234] :POSTROUTING ACCEPT [891:68234] COMMIT # Completed on Wed Apr 24 10:19:55 2002 # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002 *nat :PREROUTING ACCEPT [1:229] :POSTROUTING ACCEPT [3:450] :OUTPUT ACCEPT [3:450] -A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1 COMMIT # Completed on Wed Apr 24 10:19:55 2002
正如您所看到的,自从我们使用 -c 参数以来,每个命令现在都以字节和数据包计数器为前缀。除此之外,脚本中的命令行非常完整。现在唯一的问题是如何将输出保存到文件中。非常简单,如果您以前使用过 Linux,您应该已经知道如何执行此操作。只需将命令输出通过管道传输到您想要另存为的文件即可。这可能如下所示:
As you can see, each command has now been prefixed with the byte and packet counters since we used the -c argument. Except for this, the command-line is quite intact from the script. The only problem now, is how to save the output to a file. Quite simple, and you should already know how to do this if you have used linux at all before. It is only a matter of piping the command output on to the file that you would like to save it as. This could look like the following:
iptables-save -c > /etc/iptables-save
iptables-save -c > /etc/iptables-save
换句话说,上面的命令会将整个规则集保存到名为/etc/iptables-save的文件中,并且字节和数据包计数器仍然完好无损。
The above command will in other words save the whole rule-set to a file called /etc/iptables-save with byte and packet counters still intact.
iptables-restore 命令用于恢复使用 iptables-save 命令保存的 iptables 规则集。不幸的是,它从标准输入获取所有输入,并且在编写本文时无法从文件加载。这是 iptables-restore 的命令语法:
The iptables-restore command is used to restore the iptables rule-set that was saved with the iptables-save command. It takes all the input from standard input and can't load from files as of writing this, unfortunately. This is the command syntax for iptables-restore:
iptables-恢复 [-c] [-n]
iptables-restore [-c] [-n]
-c 参数可恢复字节和数据包计数器,如果要恢复之前使用 iptables-save 保存的计数器,则必须使用 -c 参数。这个论证也可以写成它的长形式——counters。
The -c argument restores the byte and packet counters and must be used if you want to restore counters that were previously saved with iptables-save. This argument may also be written in its long form --counters.
-n 参数告诉 iptables-restore 不要覆盖它正在写入的一个或多个表中先前写入的规则。iptables-restore 的默认行为是刷新并销毁所有先前插入的规则。短 -n 参数也可以替换为较长的格式 --noflush。
The -n argument tells iptables-restore to not overwrite the previously written rules in the table, or tables, that it is writing to. The default behavior of iptables-restore is to flush and destroy all previously inserted rules. The short -n argument may also be replaced with the longer format --noflush.
要使用 iptables-restore 命令加载规则集,我们可以通过多种方式执行此操作,但这里我们将主要介绍最简单和最常见的方法。
To load a rule-set with the iptables-restore command, we could do this in several ways, but we will mainly look at the simplest and most common way here.
猫 /etc/iptables-save | iptables-恢复-c
cat /etc/iptables-save | iptables-restore -c
以下也将起作用:
The following will also work:
iptables-restore -c < /etc/iptables-save
iptables-restore -c < /etc/iptables-save
这将捕获位于/etc/iptables-save文件中的规则集 ,然后通过管道将其传输到 iptables-restore,后者在标准输入上获取规则集,然后恢复它,包括字节和数据包计数器。开始就是这么简单。这个命令可以变化,直到被遗忘,我们可以显示不同的管道可能性,但是,这有点超出了本章的范围,因此我们将跳过该部分并将其作为练习留给读者进行实验。
This would cat the rule-set located within the /etc/iptables-save file and then pipe it to iptables-restore which takes the rule-set on the standard input and then restores it, including byte and packet counters. It is that simple to begin with. This command could be varied until oblivion and we could show different piping possibilities, however, this is a bit out of the scope of this chapter, and hence we will skip that part and leave it as an exercise for the reader to experiment with.
规则集现在应该正确加载到内核,并且一切都应该正常工作。如果没有,您可能在这些命令中遇到了错误。
The rule-set should now be loaded properly to kernel and everything should work. If not, you may possibly have run into a bug in these commands.
本章在一定程度上讨论了 iptables-save 和 iptables-restore 程序以及它们的使用方法。这两个应用程序都随 iptables 软件包一起分发,可用于快速保存大型规则集,然后将它们再次插入内核中。
This chapter has discussed the iptables-save and iptables-restore programs to some extent and how they can be used. Both applications are distributed with the iptables package, and can be used to quickly save large rulesets and then inserting them into the kernel again.
下一章将介绍 iptables 规则的语法以及如何编写格式正确的规则集。它还将根据需要展示一些需要遵守的基本良好编码风格。
The next chapter will take a look at the syntax of a iptables rule and how to write properly formatted rule-sets. It will also show some basic good coding styles to adhere to, as required.
本章和接下来的三章将详细讨论如何构建自己的规则。规则可以描述为防火墙在阻止或允许特定链中的不同连接和数据包时遵循的方向。您编写的插入链中的每一行都应被视为一条规则。我们还将讨论可用的基本匹配,以及如何使用它们,以及不同的目标以及我们如何构建我们自己的新目标(即新的子链)。
This chapter and the upcoming three chapters will discuss at length how to build your own rules. A rule could be described as the directions the firewall will adhere to when blocking or permitting different connections and packets in a specific chain. Each line you write that's inserted in a chain should be considered a rule. We will also discuss the basic matches that are available, and how to use them, as well as the different targets and how we can construct new targets of our own (i.e.,new sub chains).
本章将介绍如何创建规则以及如何编写和输入规则的原始基础知识,以便用户空间程序 iptables、不同的表以及可以向 iptables 发出的命令接受它。之后,我们将在下一章中查看 iptables 可用的所有匹配,然后更详细地了解每种类型的目标和跳转。
This chapter will deal with the raw basics of how a rule is created and how you write it and enter it so that it will be accepted by the userspace program iptables, the different tables, as well as the commands that you can issue to iptables. After that we will in the next chapter look at all the matches that are available to iptables, and then get more into detail of each type of target and jump.
正如我们已经解释过的,每条规则都是内核查看的一行,以找出如何处理数据包。如果满足所有条件或匹配,我们将执行目标或跳转指令。通常我们会用如下语法编写规则:
As we have already explained, each rule is a line that the kernel looks at to find out what to do with a packet. If all the criteria - or matches - are met, we perform the target - or jump - instruction. Normally we would write our rules in a syntax that looks something like this:
iptables [-t table ] 命令 [匹配] [目标/跳转]
iptables [-t table] command [match] [target/jump]
没有任何规定说目标指令必须是该行中的最后一个函数。但是,您通常会遵守此语法以获得最佳的可读性。无论如何,您将看到的大多数规则都是以这种方式编写的。因此,如果您阅读别人的脚本,您很可能会识别语法并轻松理解规则。
There is nothing that says that the target instruction has to be the last function in the line. However, you would usually adhere to this syntax to get the best readability. Anyway, most of the rules you'll see are written in this way. Hence, if you read someone else's script, you'll most likely recognize the syntax and easily understand the rule.
如果要使用标准表以外的表,可以在指定 [table] 的位置插入表规范。但是,没有必要明确说明要使用哪个表,因为默认情况下 iptables 使用过滤器表来执行所有命令。您也不必在规则的此时指定表。它几乎可以设置在沿线的任何地方。然而,将表规范放在开头或多或少是标准的。
If you want to use a table other than the standard table, you could insert the table specification at the point at which [table] is specified. However, it is not necessary to state explicitly what table to use, since by default iptables uses the filter table on which to implement all commands. Neither do you have to specify the table at just this point in the rule. It could be set pretty much anywhere along the line. However, it is more or less standard to put the table specification at the beginning.
但需要考虑的一件事是:该命令应该始终位于第一位,或者直接位于表规范之后。我们使用“命令”来告诉程序要做什么,例如插入规则或将规则添加到链的末尾,或者删除规则。我们将在下面进一步探讨这一点。
One thing to think about though: The command should always come first, or alternatively directly after the table specification. We use 'command' to tell the program what to do, for example to insert a rule or to add a rule to the end of the chain, or to delete a rule. We shall take a further look at this below.
匹配是我们发送到内核的规则的一部分,它详细说明了数据包的特定字符,这使得它与所有其他数据包不同。在这里,我们可以指定数据包来自哪个 IP 地址、来自哪个网络接口、预期的 IP 地址、端口、协议等。我们可以使用大量不同的匹配,我们将在本章中进一步仔细研究它们。
The match is the part of the rule that we send to the kernel that details the specific character of the packet, what makes it different from all other packets. Here we could specify what IP address the packet comes from, from which network interface, the intended IP address, port, protocol or whatever. There is a heap of different matches that we can use that we will look closer at further on in this chapter.
最后我们得到了数据包的目标。如果数据包满足所有匹配,我们会告诉内核如何处理它。例如,我们可以告诉内核将数据包发送到我们自己创建的另一个链,并且该链是该特定表的一部分。我们可以告诉内核将数据包丢弃并且不再进行进一步处理,或者我们可以告诉内核向发送者发送指定的回复。与本节的其余内容一样,我们将在本章中进一步仔细研究它。
Finally we have the target of the packet. If all the matches are met for a packet, we tell the kernel what to do with it. We could, for example, tell the kernel to send the packet to another chain that we've created ourselves, and which is part of this particular table. We could tell the kernel to drop the packet dead and do no further processing, or we could tell the kernel to send a specified reply to the sender. As with the rest of the content in this section, we'll look closer at it further on in the chapter.
-t 选项指定要使用哪个表。默认情况下,使用过滤表。我们可以使用 -t 选项指定下表之一。请注意,这是对表和链的遍历章节的一些内容的极其简短的总结 。
The -t option specifies which table to use. Per default, the filter table is used. We may specify one of the following tables with the -t option. Do note that this is an extremely brief summary of some of the contents of the Traversing of tables and chains chapter.
表 9-1。表格
Table 9-1. Tables
| 桌子 | 解释 |
|---|---|
| nat | nat表主要用于网络地址转换。根据我们的规则,经过“NAT”处理的数据包的 IP 地址会发生变化。流中的数据包仅遍历此表一次。我们假设流的第一个数据包是被允许的。同一流中的其余数据包会自动进行“NAT”或伪装等操作,并将受到与第一个数据包相同的操作。换句话说,这些将不会再次通过该表,但仍将被视为流中的第一个数据包。这是您不应在此表中进行任何过滤的主要原因,我们将进一步详细讨论这一点。PREROUTING 链用于在数据包进入防火墙后立即对其进行更改。OUTPUT 链用于更改本地生成的数据包(即 在做出路由决策之前)。最后,我们有 POSTROUTING 链,用于在数据包即将离开防火墙时对其进行更改。 The nat table is used mainly for Network Address Translation. "NAT"ed packets get their IP addresses altered, according to our rules. Packets in a stream only traverse this table once. We assume that the first packet of a stream is allowed. The rest of the packets in the same stream are automatically "NAT"ed or Masqueraded etc, and will be subject to the same actions as the first packet. These will, in other words, not go through this table again, but will nevertheless be treated like the first packet in the stream. This is the main reason why you should not do any filtering in this table, which we will discuss at greater length further on. The PREROUTING chain is used to alter packets as soon as they get in to the firewall. The OUTPUT chain is used for altering locally generated packets (i.e., on the firewall) before they get to the routing decision. Finally we have the POSTROUTING chain which is used to alter packets just as they are about to leave the firewall. |
| mangle | 该表主要用于修改数据包。除此之外,我们可以更改不同数据包的内容及其标头。例如更改 TTL、TOS 或 MARK。请注意,MARK实际上并不是对数据包的更改,而是在内核空间中设置了数据包的标记值。其他规则或程序可能会在防火墙中进一步使用此标记来过滤或执行高级路由;tc 就是一个例子。该表由五个内置链组成:PREROUTING、POSTROUTING、OUTPUT、INPUT 和 FORWARD 链。PREROUTING 用于在数据包进入防火墙时和做出路由决策之前更改数据包。POSTROUTING 用于在做出所有路由决策后立即处理数据包。OUTPUT 用于在本地生成的数据包进入路由决策后对其进行更改。INPUT 用于在数据包路由到本地计算机本身之后、用户空间应用程序实际看到数据之前更改数据包。FORWARD 用于在数据包达到第一个路由决策之后但在实际达到最后一个路由决策之前对数据包进行处理。请注意,mangle 不能用于任何类型的网络地址转换或伪装,nat 表是为此类操作而创建的。 This table is used mainly for mangling packets. Among other things, we can change the contents of different packets and that of their headers. Examples of this would be to change the TTL, TOS or MARK. Note that the MARK is not really a change to the packet, but a mark value for the packet is set in kernel space. Other rules or programs might use this mark further along in the firewall to filter or do advanced routing on; tc is one example. The table consists of five built in chains, the PREROUTING, POSTROUTING, OUTPUT, INPUT and FORWARD chains. PREROUTING is used for altering packets just as they enter the firewall and before they hit the routing decision. POSTROUTING is used to mangle packets just after all routing decisions have been made. OUTPUT is used for altering locally generated packets after they enter the routing decision. INPUT is used to alter packets after they have been routed to the local computer itself, but before the user space application actually sees the data. FORWARD is used to mangle packets after they have hit the first routing decision, but before they actually hit the last routing decision. Note that mangle can't be used for any kind of Network Address Translation or Masquerading, the nat table was made for these kinds of operations. |
| filter | 过滤表应该专门用于过滤数据包。例如,我们可以毫无问题地删除、记录、接受或拒绝数据包,就像在其他表中一样。该表内置了三个链。第一个名为 FORWARD,用于所有非本地生成的数据包,这些数据包的目的地不是我们的本地主机(换句话说,防火墙)。INPUT 用于所有发往本地主机(防火墙)的数据包,而 OUTPUT 最终用于所有本地生成的数据包。 The filter table should be used exclusively for filtering packets. For example, we could DROP, LOG, ACCEPT or REJECT packets without problems, as we can in the other tables. There are three chains built in to this table. The first one is named FORWARD and is used on all non-locally generated packets that are not destined for our local host (the firewall, in other words). INPUT is used on all packets that are destined for our local host (the firewall) and OUTPUT is finally used for all locally generated packets. |
| raw | 原始表及其链在 netfilter 中的任何其他表之前使用。它被引入使用 NOTRACK 目标。该表相当新,并且仅在编译后才可用于最新的 2.6 内核及更高版本。原始表包含两个链。PREROUTING 和 OUTPUT 链,它们将在数据包到达任何其他 netfilter 子系统之前对其进行处理。PREROUTING 链可用于所有传入本机的数据包或转发的数据包,而 OUTPUT 链可用于在本地生成的数据包到达任何其他 netfilter 子系统之前更改它们。 The raw table and its chains are used before any other tables in netfilter. It was introduced to use the NOTRACK target. This table is rather new and is only available, if compiled, with late 2.6 kernels and later. The raw table contains two chains. The PREROUTING and OUTPUT chain, where they will handle packets before they hit any of the other netfilter subsystems. The PREROUTING chain can be used for all incoming packets to this machine, or that are forwarded, while the OUTPUT chain can be used to alter the locally generated packets before they hit any of the other netfilter subsystems. |
上述详细信息应该已经解释了可用的三个不同表格的基础知识。它们应该用于完全不同的目的,并且您应该知道每个链的用途。如果你不了解它们的用法,你很可能会在你的防火墙中给自己挖一个坑,一旦有人发现它并把你推进去,你就会掉进去。我们已经在遍历表和链章节中更详细地讨论了必要的表和链。如果你没有完全理解这一点,我建议你回去再读一遍。
The above details should have explained the basics about the three different tables that are available. They should be used for totally different purposes, and you should know what to use each chain for. If you do not understand their usage, you may well dig a pit for yourself in your firewall, into which you will fall as soon as someone finds it and pushes you into it. We have already discussed the requisite tables and chains in more detail within the Traversing of tables and chains chapter. If you do not understand this fully, I advise you to go back and read through it again.
在本节中,我们将介绍所有不同的命令以及它们可以做什么。该命令告诉 iptables 如何处理我们发送到解析器的其余规则。通常我们想要在某个表或另一个表中添加或删除某些内容。iptables 可以使用以下命令:
In this section we will cover all the different commands and what can be done with them. The command tells iptables what to do with the rest of the rule that we send to the parser. Normally we would want either to add or delete something in some table or another. The following commands are available to iptables:
表 9-2。命令
Table 9-2. Commands
| 命令 | -A,--追加 |
| 例子 | iptables -A 输入... |
| 解释 | 此命令将规则附加到链的末尾。换句话说,该规则将始终放在规则集中的最后,因此最后被检查,除非您稍后附加更多规则。 |
| 命令 | -D,--删除 |
| 例子 | iptables -D 输入 --dport 80 -j 删除,iptables -D 输入 1 |
| 解释 | 此命令删除链中的规则。这可以通过两种方式完成;通过输入要匹配的整个规则(如第一个示例),或通过指定要匹配的规则编号。如果您使用第一种方法,您的条目必须与链中的条目完全匹配。如果使用第二种方法,则必须匹配要删除的规则的编号。规则从每条链的顶部开始编号,从数字 1 开始。 |
| 命令 | -R,--替换 |
| 例子 | iptables -R 输入 1 -s 192.168.0.1 -j 删除 |
| 解释 | 此命令替换指定行中的旧条目。它的工作方式与 --delete 命令相同,但不是完全删除该条目,而是用新条目替换它。其主要用途可能是在您尝试 iptables 时。 |
| 命令 | -I,--插入 |
| 例子 | iptables -I 输入 1 --dport 80 -j 接受 |
| 解释 | 在链中的某处插入规则。该规则将作为我们指定的实际数字插入。换句话说,上面的示例将作为规则 1 插入 INPUT 链中,因此从现在开始它将成为链中的第一个规则。 |
| 命令 | -L,--列表 |
| 例子 | iptables -L 输入 |
| 解释 | 此命令列出指定链中的所有条目。在上面的例子中,我们将列出 INPUT 链中的所有条目。根本不指定任何链也是合法的。在最后一种情况下,该命令将列出指定表中的所有链(要指定表,请参阅表部分)。确切的输出受到发送到解析器的其他选项的影响,例如 -n 和 -v 选项等。 |
| 命令 | -F,--冲洗 |
| 例子 | iptables -F 输入 |
| 解释 | 该命令会刷新指定链中的所有规则,相当于逐条删除每个规则,但速度要快一些。该命令可以不带选项使用,然后将删除指定表内所有链中的所有规则。 |
| 命令 | -Z,--零 |
| 例子 | iptables -Z 输入 |
| 解释 | 该命令告诉程序将特定链或所有链中的所有计数器清零。如果您将 -v 选项与 -L 命令一起使用,您可能已经在每个字段的开头看到了数据包计数器。要将此数据包计数器清零,请使用 -Z 选项。此选项的作用与 -L 相同,但 -Z 不会列出规则。如果 -L 和 -Z 一起使用(这是合法的),将首先列出链,然后将数据包计数器清零。 |
| 命令 | -N, --新链 |
| 例子 | iptables -N 允许 |
| 解释 | 该命令告诉内核在指定表中创建指定名称的新链。在上面的示例中,我们创建了一个名为 allowed 的链。请注意,不得已存在同名的链或目标。 |
| 命令 | -X, --删除链 |
| 例子 | iptables -X 允许 |
| 解释 | 该命令从表中删除指定的链。为了使该命令发挥作用,必须没有任何规则引用要删除的链。换句话说,在实际删除链之前,您必须替换或删除引用该链的所有规则。如果不带任何选项使用该命令,则除了指定表中内置的链之外的所有链都将被删除。 |
| 命令 | -P, --政策 |
| 例子 | iptables -P 输入丢弃 |
| 解释 | 此命令告诉内核在链上设置指定的默认目标或策略。所有不匹配任何规则的数据包将被强制使用该链的策略。合法目标是 DROP 和 ACCEPT(可能还有更多,如果有的话请给我发邮件)。 |
| 命令 | -E, --重命名链 |
| 例子 | iptables -E 允许 不允许 |
| 解释 | -E 命令告诉 iptables 将链的第一个名称更改为第二个名称。换句话说,在上面的示例中,我们将链的名称从 更改allowed为disallowed。请注意,这不会影响表的实际工作方式。换句话说,这只是对桌子进行了表面上的改变。 |
您应该始终输入完整的命令行,除非您只想列出 iptables 的内置帮助或获取命令的版本。要获取版本,请使用 -v 选项;要获取帮助消息,请使用 -h 选项。换句话说,和往常一样。接下来是一些可与各种不同命令一起使用的选项。请注意,我们会告诉您这些选项可以与哪些命令一起使用以及它们将产生什么效果。另请注意,我们此处不包含任何影响规则或匹配的选项。相反,我们将在本章后面的部分中讨论匹配和目标。
You should always enter a complete command line, unless you just want to list the built-in help for iptables or get the version of the command. To get the version, use the -v option and to get the help message, use the -h option. As usual, in other words. Next comes a few options that can be used with various different commands. Note that we tell you with which commands the options can be used and what effect they will have. Also note that we do not include any options here that affect rules or matches. Instead, we'll take a look at matches and targets in a later section of this chapter.
表 9-3。选项
Table 9-3. Options
| 选项 | -v, --详细 |
| 使用的命令 | --列表、--追加、--插入、--删除、--替换 |
| 解释 | 该命令提供详细输出,主要与 --list 命令一起使用。如果与 --list 命令一起使用,它将输出接口地址、规则选项和 TOS 掩码。如果设置了 --verbose 选项,--list 命令还将包括每个规则的字节和数据包计数器。这些计数器使用 K (x1000)、M (x1,000,000) 和 G (x1,000,000,000) 乘法器。要推翻这一点并获得准确的输出,您可以使用 -x 选项,稍后将对此进行描述。如果该选项与 --append、--insert、--delete 或 --replace 命令一起使用,程序将输出有关规则如何解释以及是否正确插入等的详细信息。 |
| 选项 | -x, --精确 |
| 使用的命令 | - 列表 |
| 解释 | 此选项扩展数字。换句话说,--list 的输出将不包含 K、M 或 G 乘数。相反,我们将从数据包和字节计数器中获得与相关规则匹配的数据包和字节数的准确输出。请注意,此选项仅在 --list 命令中可用,与任何其他命令无关。 |
| 选项 | -n, --数字 |
| 使用的命令 | - 列表 |
| 解释 | 该选项告诉 iptables 输出数值。IP 地址和端口号将使用其数值而不是主机名、网络名称或应用程序名称来打印。该选项仅适用于 --list 命令。如果可能,此选项会覆盖将所有数字解析为主机和名称的默认设置。 |
| 选项 | --行号 |
| 使用的命令 | - 列表 |
| 解释 | --line-numbers 命令与 --list 命令一起用于输出行号。使用此选项,每个规则都会输出及其编号。在插入规则时可以方便地知道哪个规则有哪个编号。此选项仅适用于 --list 命令。 |
| 选项 | -c,--设置计数器 |
| 使用的命令 | --插入、--追加、--替换 |
| 解释 | 创建规则或以某种方式修改规则时使用此选项。然后,我们可以使用该选项来初始化规则的数据包和字节计数器。语法类似于 --set-counters 20 4000,它会告诉内核将数据包计数器设置为 20,将字节计数器设置为 4000。 |
| 选项 | --modprobe |
| 使用的命令 | 全部 |
| 解释 | --modprobe 选项用于告诉 iptables 在探测模块或将它们添加到内核时使用哪个模块。如果您的 modprobe 命令不在搜索路径中的某个位置等,则可以使用它。在这种情况下,可能有必要指定此选项,以便程序知道在未加载所需模块的情况下该怎么做。该选项可与所有命令一起使用。 |
本章非常简单地讨论了 iptables 的一些基本命令以及可在 netfilter 中使用的表。正如您所看到的,这些命令可以对加载到内核中的 netfilter 包执行许多不同的操作。
This chapter has discussed some of the basic commands for iptables and the tables very briefly that can be used in netfilter. The commands makes it possible to do quite a lot of different operations on the netfilter package loaded inside kernel as you have seen.
下一章将讨论 iptables 和 netfilter 中所有可用的匹配。这是一个非常沉重和漫长的章节,我谦虚地建议你不需要真正详细地学习每一个可用的匹配,除了你将要使用的那些。一个好主意可能是简要了解每场比赛的作用,然后在需要时更好地掌握它们。
The next chapter will discuss all the available matches in iptables and netfilter. This is a very heavy and long chapter, and I humbly suggest that you don't need to actually learn every single match available in any detail, except the ones that you are going to use. A good idea might be to get a brief understanding of what each match does, and then get a better grasp on them as you need them.
在本章中,我们将更多地讨论匹配。我选择将比赛范围缩小为五个不同的子类别。首先,我们有通用的 matches,它可以在所有规则中使用。然后我们就有了只能应用于 TCP 数据包的TCP 匹配。我们有 只能应用于 UDP 数据包的 UDP 匹配,以及只能应用于 ICMP 数据包的ICMP 匹配。最后我们还有特殊的匹配,例如状态、所有者和限制匹配等。这些决赛比赛又被缩小到更多的子类别,尽管它们不一定是不同的比赛。我希望这是一个合理的分解,并且所有人都能理解。
In this chapter we'll talk a bit more about matches. I've chosen to narrow down the matches into five different subcategories. First of all we have the generic matches, which can be used in all rules. Then we have the TCP matches which can only be applied to TCP packets. We have UDP matches which can only be applied to UDP packets, and ICMP matches which can only be used on ICMP packets. Finally we have special matches, such as the state, owner and limit matches and so on. These final matches have in turn been narrowed down to even more subcategories, even though they might not necessarily be different matches at all. I hope this is a reasonable breakdown and that all people out there can understand it.
如果您阅读了前面的章节,您可能已经明白,匹配是指定数据包中必须为真(或假)的特殊条件的东西。单个规则可以包含任意类型的多个匹配。例如,我们可能希望匹配来自局域网上特定主机的数据包,并且最重要的是仅匹配来自该主机上特定端口的数据包。然后,我们可以使用匹配来告诉规则仅对具有特定源地址的数据包应用目标(或跳转规范),这些数据包进入连接到 LAN 的接口,并且数据包必须是指定端口之一。如果这些匹配中的任何一个失败(例如,源地址不正确,但其他所有内容都为真),则整个规则失败,并在数据包上测试下一条规则。然而,如果所有匹配都为真,
As you may already understand if you have read the previous chapters, a match is something that specifies a special condition within the packet that must be true (or false). A single rule can contain several matches of any kind. For example, we may want to match packets that come from a specific host on a our local area network, and on top of that only from specific ports on that host. We could then use matches to tell the rule to only apply the target - or jump specification - on packets that have a specific source address, that come in on the interface that connects to the LAN and the packets must be one of the specified ports. If any one of these matches fails (e.g., the source address isn't correct, but everything else is true), the whole rule fails and the next rule is tested on the packet. If all matches are true, however, the target specified by the rule is applied.
本节将处理通用匹配。通用匹配是一种始终可用的匹配,无论我们正在使用哪种类型的协议,或者我们加载的任何匹配扩展。使用这些匹配根本不需要任何特殊参数;换句话说。我还在此处包含了 --protocol 匹配,尽管它更具体于协议匹配。例如,如果我们想使用 TCP 匹配,我们需要使用 --protocol 匹配并将 TCP 作为选项发送到匹配。然而,--protocol 本身也是一个匹配,因为它可以用来匹配特定的协议。以下比赛始终可用。
This section will deal with Generic matches. A generic match is a kind of match that is always available, whatever kind of protocol we are working on, or whatever match extensions we have loaded. No special parameters at all are needed to use these matches; in other words. I have also included the --protocol match here, even though it is more specific to protocol matches. For example, if we want to use a TCP match, we need to use the --protocol match and send TCP as an option to the match. However, --protocol is also a match in itself, since it can be used to match specific protocols. The following matches are always available.
表 10-1。通用匹配
Table 10-1. Generic matches
| 匹配 | -p, --协议 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp |
| 解释 | 该匹配用于检查某些协议。协议示例有 TCP、UDP 和 ICMP。该协议必须是内部指定的 TCP、UDP 或 ICMP 之一。它还可能采用/etc/protocols文件中指定的值,如果找不到该协议,它将返回错误。协议也可以是整数值。例如,ICMP协议为整数值1,TCP为6,UDP为17。最后,也可以取值ALL。ALL表示仅匹配 TCP、UDP 和 ICMP。如果此匹配项的整数值为零 (0),则表示所有协议,如果未使用 --protocol 匹配,则这又是默认行为。这场比赛也可以逆转!签名,所以--协议!tcp 意味着匹配 UDP 和 ICMP。 |
| 匹配 | -s、--src、--源 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -s 192.168.1.1 |
| 解释 | 这是源匹配,用于根据数据包的源 IP 地址来匹配数据包。主形式可用于匹配单个 IP 地址,例如192.168.1.1。通过指定网络掩码左侧的 1 (1) 数量,它还可以与 CIDR“位”形式的网络掩码一起使用。这意味着我们可以添加 /24以使用255.255.255.0网络掩码。然后我们可以匹配整个 IP 范围,例如我们的本地网络或防火墙后面的网段。该行看起来像 192.168.0.0/24。这将匹配 192.168.0.x范围内的所有数据包。另一种方法是使用255.255.255.255形式的常规网络掩码(即 192.168.0.0/255.255.255.0)。我们还可以用 ! 来反转匹配。就像以前一样。换句话说,如果我们使用 --source 形式的匹配!192.168.0.0/24,我们将匹配源地址不在 192.168.0.x范围内的所有数据包。默认匹配所有 IP 地址。 |
| 匹配 | -d,--dst,--目的地 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -d 192.168.1.1 |
| 解释 | --destination 匹配用于根据数据包的目标地址进行匹配。它的工作原理与 --source 匹配几乎相同,并且具有相同的语法,只是匹配基于数据包的目的地。为了匹配 IP 范围,我们可以以精确的网络掩码形式添加网络掩码,或者以从网络掩码位左侧开始计数的 1 的数量添加网络掩码。例如: 192.168.0.0/255.255.255.0和 192.168.0.0/24。这两者是等价的。我们还可以用 ! 来反转整个比赛。签到,和以前一样。 - 目的地 !换句话说,192.168.0.1 将匹配除发往192.168.0.1 IP 地址的数据包之外的所有数据包。 |
| 匹配 | -i, --接口内 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -i eth0 |
| 解释 | 此匹配用于数据包进入的接口。请注意,此选项仅在 INPUT、FORWARD 和 PREROUTING 链中合法,并且在其他地方使用时将返回错误消息。如果未指定特定接口,则此匹配的默认行为是假定字符串值 +。+ 值用于匹配字母和数字的字符串。换句话说,单个 + 会告诉内核匹配所有数据包,而不考虑它来自哪个接口。+ 字符串也可以附加到接口类型后,因此 eth+ 将表示所有以太网设备。我们还可以在 ! 的帮助下反转该选项的含义。符号。该行的语法看起来类似于 -i !eth0,它将匹配除 eth0 之外的所有传入接口。 |
| 匹配 | -o, --out 接口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 转发 -o eth0 |
| 解释 | --out-interface 匹配用于数据包离开的接口。请注意,此匹配仅在 OUTPUT、FORWARD 和 POSTROUTING 链中可用,实际上与 --in-interface 匹配相反。除此之外,它的工作方式与 --in-interface 匹配几乎相同。+ 扩展被理解为匹配所有类似类型的设备,因此 eth+ 将匹配所有 eth 设备,依此类推。要反转匹配的含义,您可以使用 ! 登录方式与 --in-interface 匹配完全相同。如果未指定 --out-interface,则此匹配的默认行为是匹配所有设备,无论数据包要去往何处。 |
| 匹配 | -f,--片段 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -f |
| 解释 | 该匹配用于匹配分段数据包的第二部分和第三部分。其原因是,对于分段数据包,无法识别分段的源端口或目标端口,也无法识别 ICMP 类型等。此外,在相当特殊的情况下,碎片数据包可能会被用来对其他计算机进行复合攻击。像这样的数据包片段不会被其他规则匹配,因此创建了此匹配。该选项也可以与 ! 符号; 然而,在这种情况下!符号必须在匹配之前,即 ! -F。当此匹配反转时,我们匹配所有标头片段和/或未分段的数据包。这意味着我们匹配分片数据包的所有第一个片段,而不是第二个、第三个等等。我们还匹配传输过程中未分段的所有数据包。另请注意,您可以使用内核中非常好的碎片整理选项。其次要注意的是,如果您使用连接跟踪,您将不会看到任何碎片数据包,因为它们在到达 iptables 中的任何链或表之前就已被处理。 |
本节将描述隐式加载的匹配项。隐式匹配是暗示的、理所当然的、自动的。例如,当我们在没有任何进一步条件的情况下匹配 --protocol tcp 时。目前存在针对三种不同协议的三种类型的隐式匹配。它们是TCP 匹配、UDP 匹配和ICMP 匹配。基于 TCP 的匹配包含一组仅适用于 TCP 数据包的唯一标准。基于 UDP 的匹配包含另一组仅适用于 UDP 数据包的条件。ICMP 数据包也是如此。另一方面,可能存在显式加载的显式匹配。显式匹配不是暗示或自动的,您必须具体指定它们。对于这些,您可以使用 -m 或 --match 选项,我们将在下一节中讨论。
This section will describe the matches that are loaded implicitly. Implicit matches are implied, taken for granted, automatic. For example when we match on --protocol tcp without any further criteria. There are currently three types of implicit matches for three different protocols. These are TCP matches, UDP matches and ICMP matches. The TCP based matches contain a set of unique criteria that are available only for TCP packets. UDP based matches contain another set of criteria that are available only for UDP packets. And the same thing for ICMP packets. On the other hand, there can be explicit matches that are loaded explicitly. Explicit matches are not implied or automatic, you have to specify them specifically. For these you use the -m or --match option, which we will discuss in the next section.
这些匹配是特定于协议的,并且仅在处理 TCP 数据包和流时才可用。要使用这些匹配,您需要在尝试使用它们之前在命令行上指定 --protocol tcp。请注意,--protocol tcp 匹配必须位于协议特定匹配的左侧。从某种意义上说,这些匹配是隐式加载的,就像 UDP和ICMP 匹配是隐式加载的一样。其他匹配将在本节的后续部分( TCP 匹配部分之后)中查看。
These matches are protocol specific and are only available when working with TCP packets and streams. To use these matches, you need to specify --protocol tcp on the command line before trying to use them. Note that the --protocol tcp match must be to the left of the protocol specific matches. These matches are loaded implicitly in a sense, just as the UDP and ICMP matches are loaded implicitly. The other matches will be looked over in the continuation of this section, after the TCP match section.
表 10-2。TCP 匹配
Table 10-2. TCP matches
| 匹配 | --运动,--源端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp --sport 22 |
| 解释 | --source-port 匹配用于根据数据包的源端口来匹配数据包。如果没有它,我们意味着所有源端口。该匹配可以采用服务名称或端口号。如果指定服务名称,则该服务名称必须位于/etc/services中文件,因为 iptables 使用此文件来查找。如果您按端口号指定端口,则规则的加载速度会稍快一些,因为 iptables 不必检查服务名称。但是,与使用服务名称相比,匹配可能会更难阅读。如果您正在编写包含 200 条或更多规则的规则集,那么您绝对应该使用端口号,因为差异非常明显。(在速度较慢的机器上,如果您配置了包含 1000 条左右规则的大型规则集,则可能会产生多达 10 秒的差异)。您还可以使用 --source-port 匹配来匹配任何范围的端口,例如 --source-port 22:80。此示例将匹配 22 到 80 之间的所有源端口。如果省略指定第一个端口,则假定端口 0(隐式)。--source-port :80 将匹配端口 0 到 80。如果省略最后一个端口规范,则假定端口 65535。如果您要编写 --source-port 22:,您将指定从端口 22 到端口 65535 的所有端口的匹配。如果您反转端口范围,iptables 会自动反转您的反转。如果您编写 --source-port 80:22,它会简单地解释为 --source-port 22:80。您还可以通过添加 ! 来反转匹配。符号。例如,--源端口!22 意味着您想要匹配除端口 22 之外的所有端口。反转也可以与端口范围一起使用,然后看起来像 --source-port !22:80,这又意味着您想要匹配除端口 22 到 80 之外的所有端口。请注意,此匹配不处理多个单独的端口和端口范围。有关这些的更多信息,请查看多端口匹配扩展。 |
| 匹配 | --dport, --目标端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp --dport 22 |
| 解释 | 此匹配用于根据 TCP 数据包的目标端口来匹配 TCP 数据包。它使用与 --source-port 匹配完全相同的语法。它了解端口和端口范围规范以及反转。它还会颠倒端口范围规格中的高端口和低端口,如上所述。如果端口范围规范中省略了高端口或低端口,则匹配也将采用 0 和 65535 值。换句话说,与 --source-port 语法完全相同。请注意,此匹配不处理多个单独的端口和端口范围。有关这些的更多信息,请查看多端口匹配扩展。 |
| 匹配 | --tcp-标志 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -p tcp --tcp-flags SYN、FIN、ACK SYN |
| 解释 | 此匹配用于匹配数据包中的 TCP 标志。首先,匹配需要一个要比较的标志列表(掩码),其次它需要应设置为 1 或打开的标志列表。两个列表都应该以逗号分隔。匹配器知道 SYN、ACK、FIN、RST、URG、PSH 标志,并且还识别单词 ALL 和 NONE。ALL 和 NONE 几乎是自我描述的:ALL 意味着使用所有标志,NONE 意味着不使用该选项的标志。换句话说,--tcp-flags ALL NONE 意味着检查所有 TCP 标志,如果没有设置任何标志,则进行匹配。这个选项也可以用 ! 来反转。符号。例如,如果我们指定 ! SYN,FIN,ACK SYN,我们将得到一个匹配项,该匹配项将匹配设置了 ACK 和 FIN 位但不设置 SYN 位的数据包。另请注意,逗号分隔不应包含空格。 |
| 匹配 | --syn |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -p tcp --syn |
| 解释 | --syn 匹配或多或少是 ipchains 时代的旧遗物,并且仍然存在,以实现向后兼容性以及使从一个到另一个的转换变得更容易。如果数据包设置了 SYN 位并且未设置 ACK 和 RST 位,则它用于匹配数据包。换句话说,该命令与 --tcp-flags SYN、RST、ACK SYN 匹配完全相同。此类数据包主要用于向服务器请求新的 TCP 连接。如果阻止这些数据包,则应该有效阻止所有传入连接尝试。但是,您不会阻止传出连接,这是当今许多漏洞利用的方法(例如,破解合法服务,然后安装程序或类似程序,以启动与主机的现有连接,而不是打开新端口在上面)。这场比赛也可以用 ! 登录此,!——辛,方式。这将匹配设置了 RST 或 ACK 位的所有数据包,换句话说,已建立连接中的数据包。 |
| 匹配 | --tcp 选项 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -p tcp --tcp-选项 16 |
| 解释 | 此匹配用于根据数据包的 TCP 选项来匹配数据包。TCP 选项是标头的特定部分。这部分由 3 个不同的字段组成。第一个是 8 位长,告诉我们该流中使用了哪些选项,第二个也是 8 位长,告诉我们选项字段有多长。这个长度字段的原因是 TCP 选项是可选的。为了符合标准,我们不需要实现所有的选项,而是我们可以只看它是什么类型的选项,如果我们不支持它,我们只看长度字段,然后可以跳过这个数据。此匹配用于根据十进制值匹配不同的 TCP 选项。它也可以与 ! 标志,以便匹配匹配除了给定匹配的选项之外的所有 TCP 选项。互联网工程任务组 负责维护互联网上使用的所有标准号码的列表。 |
本节描述仅与 UDP 数据包一起使用的匹配。当您指定 --protocol UDP 匹配时,这些匹配会隐式加载,并将在指定后可用。请注意,UDP 数据包不是面向连接的,因此不需要在数据包中设置不同的标志来提供有关数据报应该执行的操作的数据,例如打开或关闭连接,或者它们只是简单地应该发送数据。UDP 数据包也不需要任何类型的确认。如果它们丢失,它们就只是丢失(不考虑 ICMP 错误消息等)。这意味着 UDP 数据包上的匹配项比 TCP 数据包上的匹配项要少得多。请注意,即使 UDP 或 ICMP 数据包被视为无连接协议,状态机也会处理所有类型的数据包。状态机在 UDP 数据包上的工作方式与在 TCP 数据包上的工作方式几乎相同。
This section describes matches that will only work together with UDP packets. These matches are implicitly loaded when you specify the --protocol UDP match and will be available after this specification. Note that UDP packets are not connection oriented, and hence there is no such thing as different flags to set in the packet to give data on what the datagram is supposed to do, such as open or closing a connection, or if they are just simply supposed to send data. UDP packets do not require any kind of acknowledgment either. If they are lost, they are simply lost (Not taking ICMP error messaging etc into account). This means that there are quite a lot less matches to work with on a UDP packet than there is on TCP packets. Note that the state machine will work on all kinds of packets even though UDP or ICMP packets are counted as connectionless protocols. The state machine works pretty much the same on UDP packets as on TCP packets.
表 10-3。UDP 匹配
Table 10-3. UDP matches
| 匹配 | --运动,--源端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p udp --sport 53 |
| 解释 | 该匹配的工作方式与 TCP 匹配的工作方式完全相同。它用于根据数据包的源 UDP 端口对数据包进行匹配。它支持具有相同语法的端口范围、单个端口和端口反转。要指定 UDP 端口范围,您可以使用 22:80,它将匹配 UDP 端口 22 到 80。如果省略第一个值,则假定端口 0。如果省略最后一个端口,则假定为端口 65535。如果高端口在低端口之前,端口会自动交换位置。单个 UDP 端口匹配如上例所示。要反转端口匹配,请添加 ! 标志,--源端口!53. 这将匹配除端口 53 之外的所有端口。匹配可以理解服务名称,只要它们在/etc/services中可用文件。请注意,此匹配不处理多个单独的端口和端口范围。有关这方面的更多信息,请查看多端口匹配扩展。 |
| 匹配 | --dport, --目标端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p udp --dport 53 |
| 解释 | 此匹配与上面的 --source-port 相同。它与等效 TCP 匹配完全相同,但此处适用于 UDP 数据包。它根据 UDP 目标端口匹配数据包。该匹配处理端口范围、单个端口和反转。要匹配您使用的单个端口,例如 --destination-port 53,要反转它,您将使用 --destination-port !53. 第一个将匹配所有前往端口 53 的 UDP 数据包,而第二个将匹配除前往目标端口 53 之外的数据包。要指定端口范围,例如,您可以使用 --destination-port 9:19。此示例将匹配发往 UDP 端口 9 到 19 的所有数据包。如果省略第一个端口,则假定为端口 0。如果省略第二个端口,则假定为端口 65535。如果高端口放置在低端口之前,它们会自动交换位置,所以低端口先于高端口结束。请注意,此匹配不处理多个端口和端口范围。有关这方面的更多信息,请查看多端口匹配扩展。 |
这些是ICMP 匹配。这些数据包比 UDP 数据包更加短暂,即寿命较短,因为它们是无连接的。ICMP协议主要用于错误报告和连接控制等。ICMP 不是一个从属于 IP 协议的协议,而是一个增强 IP 协议并帮助处理错误的协议。ICMP 数据包的标头与 IP 标头非常相似,但在许多方面有所不同。该协议的主要特征是类型标头,它告诉我们数据包的用途。一个例子是,如果我们尝试访问一个无法访问的 IP 地址,通常会得到一个无法访问的 ICMP 主机作为回报。有关 ICMP 类型的完整列表,请参阅ICMP 类型附录。ICMP 数据包只有一个 ICMP 特定匹配可用,希望这应该足够了。当我们使用 --protocol ICMP 匹配时,此匹配会被隐式加载,并且我们会自动访问它。请注意,还可以使用所有通用匹配,以便我们可以在源地址和目标地址上进行匹配。
These are the ICMP matches. These packets are even more ephemeral, that is to say short lived, than UDP packets, in the sense that they are connectionless. The ICMP protocol is mainly used for error reporting and for connection controlling and suchlike. ICMP is not a protocol subordinated to the IP protocol, but more of a protocol that augments the IP protocol and helps in handling errors. The headers of ICMP packets are very similar to those of the IP headers, but differ in a number of ways. The main feature of this protocol is the type header, that tells us what the packet is for. One example is, if we try to access an unaccessible IP address, we would normally get an ICMP host unreachable in return. For a complete listing of ICMP types, see the ICMP types appendix. There is only one ICMP specific match available for ICMP packets, and hopefully this should suffice. This match is implicitly loaded when we use the --protocol ICMP match and we get access to it automatically. Note that all the generic matches can also be used, so that among other things we can match on the source and destination addresses.
表 10-4。ICMP 匹配
Table 10-4. ICMP matches
| 匹配 | --icmp 类型 | ||
| 核心 | 2.3、2.4、2.5 和 2.6 | ||
| 例子 | iptables -A 输入 -p icmp --icmp 类型 8 | ||
| 解释 | 该匹配用于指定要匹配的 ICMP 类型。ICMP 类型可以通过其数值或名称来指定。RFC 792 中指定了数值。要查找 ICMP 名称值的完整列表,请执行 iptables --protocol icmp --help,或检查ICMP 类型附录。这场比赛也可以用 ! 登录此 --icmp-type !8、时尚。请注意,某些 ICMP 类型已过时,而其他类型对于未受保护的主机来说可能又是“危险的”,因为它们可能会将数据包重定向到错误的位置。类型和代码也可以通过它们的类型名称、数字类型和类型/代码来指定。例如 --icmp-type 网络重定向、--icmp-type 8 或 --icmp-type 8/0。要获得完整的名称列表,请输入 iptables -p icmp --help。 This match is used to specify the ICMP type to match. ICMP types can be specified either by their numeric values or by their names. Numerical values are specified in RFC 792. To find a complete listing of the ICMP name values, do an iptables --protocol icmp --help, or check the ICMP types appendix. This match can also be inverted with the ! sign in this, --icmp-type ! 8, fashion. Note that some ICMP types are obsolete, and others again may be "dangerous" for an unprotected host since they may, among other things, redirect packets to the wrong places. The type and code may also be specified by their typename, numeric type, and type/code as well. For example --icmp-type network-redirect, --icmp-type 8 or --icmp-type 8/0. For a complete listing of the names, type iptables -p icmp --help.
|
与 TCP 和 UDP 协议相比,SCTP(即流控制传输协议)是网络领域中相对较新的出现。SCTP特性 一章更详细地解释了该协议。通过在 iptables 命令行中添加 -p sctp 匹配来加载隐式 SCTP 匹配。
SCTP or Stream Control Transmission Protocol is a relatively new occurence in the networking domain in comparison to the TCP and UDP protocols. The SCTP Characteristics chapter explains the protocol more in detail. The implicit SCTP matches are loaded through adding the -p sctp match to the command line of iptables.
SCTP 协议是由一些较大的电信和交换机/网络制造商开发的,该协议特别适合具有高可靠性和高吞吐量的大型并发事务。
The SCTP protocol was developed by some of the larger telecom and switch/network manufacturers out there, and the protocol is specifically well suited for large simultaneous transactions with high reliability and high throughput.
表 10-5。SCTP比赛
Table 10-5. SCTP matches
| 匹配 | --源端口,--运动 |
| 核心 | 2.6 |
| 例子 | iptables -A 输入 -p sctp --源端口 80 |
| 解释 | --source-port match 用于根据 SCTP 数据包标头中的源端口来匹配 SCTP 数据包。该端口可以是单个端口(如上例所示),也可以是指定为 --source-port 20:100 的一系列端口,也可以用 ! 符号反转。例如,这看起来像 --source-port !25.源端口是无符号16位整数,因此最大值为65535,最小值为0。 The --source-port match is used to match an SCTP packet based on the source port in the SCTP packet header. The port can either be a single port, as in the example above, or a range of ports specified as --source-port 20:100, or it can also be inverted with the !-sign. This looks, for example, like --source-port ! 25. The source port is an unsigned 16 bit integer, so the maximum value is 65535 and the lowest value is 0. |
| 匹配 | --目标端口,--dport |
| 核心 | 2.6 |
| 例子 | iptables -A 输入 -p sctp --目标端口 80 |
| 解释 | 此匹配用于 SCTP 数据包的目标端口。所有 SCTP 数据包的标头中都包含目标端口,就像源端口一样。可以按照上面的示例指定端口,也可以指定端口范围,例如 --destination-port 6660:6670。该命令也可以用 ! 符号反转,例如 --destination-port ! 80。此示例将匹配除端口 80 之外的所有数据包。这同样适用于目标端口和源端口,最高端口为 65535,最低端口为 0。 This match is used for the destination port of the SCTP packets. All SCTP packets contain a destination port, just as it does a source port, in the headers. The port can be either specified as in the example above, or with a port range such as --destination-port 6660:6670. The command can also be inverted with the !-sign, for example, --destination-port ! 80. This example would match all packets but those to port 80. The same applies for destination ports as for source ports, the highest port is 65535 and the lowest is 0. |
| 匹配 | --块类型 |
| 核心 | 2.6 |
| 例子 | iptables -A INPUT -p sctp --chunk-types 任何 INIT、INIT_ACK |
| 解释 | 这与 SCTP 数据包的块类型匹配。目前有许多不同的块类型可用。有关完整列表,请参见下文。匹配以 --chunk-types 关键字开始,然后以一个标志继续,指出我们是否要匹配全部、任何或无。此后,您指定要匹配的 SCTP 块类型。块类型可在下面的单独列表中找到。 This matches the chunk type of the SCTP packet. Currently there are a host of different chunk types available. For a complete list, see below. The match begins with the --chunk-types keyword, and then continues with a flag noting if we are to match all, any or none. After this, you specify the SCTP Chunk Types to match for. The Chunk Types are available in the separate list below. 此外,标志还可以带有一些块标志。例如,这可以以 --chunk-types any DATA:Be 的形式完成。这些标志特定于每个 SCTP 块类型,并且必须根据此表后面的单独列表有效。 Additionally, the flags can take some Chunk Flags as well. This is done for example in the form --chunk-types any DATA:Be. The flags are specific for each SCTP Chunk type and must be valid according to the separate list after this table. 如果使用大写字母,则必须设置该标志,如果设置小写字母,则必须取消设置该标志以匹配。整个比赛可以通过使用 ! 来反转。在 --chunk-types 关键字之后签名。例如,--chunk-types!任何 DATA:Be 都会匹配除此模式之外的任何内容。 If an upper case letter is used, the flag must be set, and if a lower case flag is set it must be unset to match. The whole match can be inversed by using an ! sign just after the --chunk-types keyword. For example, --chunk-types ! any DATA:Be would match anything but this pattern. |
以下是 --chunk-types 匹配将识别的块类型列表。如您所见,该列表相当广泛,但最常用的数据包是 DATA 和 SACK 数据包。其余的主要用于控制关联。
Below is the list of chunk types that the --chunk-types match will recognize. The list is quite extensive as you can see, but the mostly used packets are DATA and SACK packets. The rest are mostly used for controlling the association.
--chunk-types 中使用的 SCTP 块类型
SCTP Chunk types as used in --chunk-types
中止
ABORT
阿斯康夫
ASCONF
ASCONF_ACK
ASCONF_ACK
Cookie_ACK
COOKIE_ACK
COOKIE_ECHO
COOKIE_ECHO
数据
DATA
ECN_CWR
ECN_CWR
ECN_ECNE
ECN_ECNE
错误
ERROR
心跳
HEARTBEAT
心跳确认
HEARTBEAT_ACK
在里面
INIT
初始化_ACK
INIT_ACK
解雇
SACK
关闭
SHUTDOWN
关闭_ACK
SHUTDOWN_ACK
关机_完成
SHUTDOWN_COMPLETE
以下标志可以与 --chunk-types 匹配一起使用,如上所示。根据RFC 2960 - 流控制传输协议,所有其余标志都被保留或未使用,并且必须设置为 0。幸运的是,Iptables 目前不包含任何强制执行此操作的措施,因为它会成为另一个问题比如之前在IP协议中实现ECN时所经历的情况。
The following flags can be used with the --chunk-types match as seen above. According to the RFC 2960 - Stream Control Transmission Protocol all the rest of the flags are reserved or not in use, and must be set to 0. Iptables does currently not contain any measures to enforce this, fortunately, since it begs to become another problem such as the one previously experienced when ECN was implemented in the IP protocol.
--chunk-types 中使用的 SCTP 块标志
SCTP Chunk flags as used in --chunk-types
DATA - U or u for Unordered bit, B or b for Beginning fragment bit and E or e for Ending fragment bit.
ABORT -T 或t 为TCB 销毁标志。
ABORT - T or t for TCB destroy flag.
SHUTDOWN_COMPLETE -T 或t 为TCB 被破坏标志。
SHUTDOWN_COMPLETE - T or t for TCB destroyed flag.
显式匹配是那些必须使用 -m 或 --match 选项专门加载的匹配。例如,状态匹配需要在输入要使用的实际匹配之前使用指令 -m state。其中一些匹配可能是特定于协议的。有些可能未与任何特定协议连接 - 例如连接状态。这些可能是NEW(尚未建立的连接的第一个数据包)、ESTABLISHED(已在内核中注册的连接)、RELATED(由较旧的已建立连接创建的新连接)等。是为了测试或实验目的而演变的,或者只是为了说明 iptables 的能力。这反过来意味着并非所有这些匹配乍一看都有任何用处。尽管如此,您个人很可能会发现特定显式匹配的用途。并且随着每个新的 iptables 版本的出现,总会有新的出现。您是否找到它们的用途取决于您的想象力和需求。隐式加载的匹配和显式加载的匹配之间的区别在于,例如,当您匹配 TCP 数据包的属性时,隐式加载的匹配将自动加载,而显式加载的匹配永远不会自动加载 - 这取决于您发现并激活显式匹配。
Explicit matches are those that have to be specifically loaded with the -m or --match option. State matches, for example, demand the directive -m state prior to entering the actual match that you want to use. Some of these matches may be protocol specific . Some may be unconnected with any specific protocol - for example connection states. These might be NEW (the first packet of an as yet unestablished connection), ESTABLISHED (a connection that is already registered in the kernel), RELATED (a new connection that was created by an older, established one) etc. A few may just have been evolved for testing or experimental purposes, or just to illustrate what iptables is capable of. This in turn means that not all of these matches may at first sight be of any use. Nevertheless, it may well be that you personally will find a use for specific explicit matches. And there are new ones coming along all the time, with each new iptables release. Whether you find a use for them or not depends on your imagination and your needs. The difference between implicitly loaded matches and explicitly loaded ones, is that the implicitly loaded matches will automatically be loaded when, for example, you match on the properties of TCP packets, while explicitly loaded matches will never be loaded automatically - it is up to you to discover and activate explicit matches.
addrtype 模块根据地址类型匹配数据包。地址类型在内核内部用于将不同的数据包分为不同的类别。通过此匹配,您将能够根据内核的地址类型来匹配所有数据包。应该注意的是,不同地址类型的确切含义在第 3 层协议之间有所不同。不过,我将在这里给出简要的一般描述,但有关更多信息,我建议阅读Linux 高级路由和流量控制 HOW-TO和使用 Linux 的策略路由。可用的类型如下:
The addrtype module matches packets based on the address type. The address type is used inside the kernel to put different packets into different categories. With this match you will be able to match all packets based on their address type according to the kernel. It should be noted that the exact meaning of the different address types varies between the layer 3 protocols. I will give a brief general description here however, but for more information I suggest reading Linux Advanced Routing and Traffic Control HOW-TO and Policy Routing using Linux. The available types are as follows:
表 10-6。地址类型
Table 10-6. Address types
| 类型 | 描述 |
|---|---|
| 任播 | 这是一种一对多关联连接类型,其中只有众多接收方主机之一实际接收数据。例如,这在 DNS 中实现。您只有一个根服务器地址,但它实际上有多个位置,您的数据包将被定向到最近的工作服务器。未在 Linux IPv4 中实现。 This is a one-to-many associative connection type, where only one of the many receiver hosts actually receives the data. This is for example implemented in DNS. You have single address to a root server, but it actually has several locations and your packet will be directed to the closest working server. Not implemented in Linux IPv4. |
| 黑洞 | 黑洞地址只会删除数据包并且不发送回复。它基本上就像太空中的黑洞一样。这是在linux的路由表中配置的。 A blackhole address will simply delete the packet and send no reply. It works as a black hole in space basically. This is configured in the routing tables of linux. |
| 播送 | 广播数据包是以一对多关系发送给特定网络中的每个人的单个数据包。例如,这用于 ARP 解析,其中发送单个数据包,请求有关如何到达特定 IP 的信息,然后权威主机回复该主机的正确 MAC 地址。 A broadcast packet is a single packet sent to everyone in a specific network in a one-to-many relation. This is for example used in ARP resolution, where a single packet is sent out requesting information on how to reach a specific IP, and then the host that is authoritative replies with the proper MAC address of that host. |
| 当地的 | 我们正在处理的主机的本地地址。例如 127.0.0.1。 An address that is local to the host we are working on. 127.0.0.1 for example. |
| 组播 | 多播数据包使用最短距离发送到多个主机,并且仅将一个数据包发送到每个路径点,其中对于订阅特定多播地址的每个主机/路由器来说,该数据包将是多个副本。常用于流媒体的一种方式,例如视频或声音。 A multicast packet is sent to several hosts using the shortest distance and only one packet is sent to each waypoint where it will be multiple copies for each host/router subscribing to the specific multicast address. Commonly used in one way streaming media such as video or sound. |
| 网络地址转换 | 已由内核进行 NAT 转换的地址。 An address that has been NAT'ed by the kernel. |
| 禁止 | 与黑洞相同,只是会生成禁止的答案。在 IPv4 情况下,这意味着将生成 ICMP 通信禁止(类型 3,代码 13)答案。 Same as blackhole except that a prohibited answer will be generated. In the IPv4 case, this means an ICMP communication prohibited (type 3, code 13) answer will be generated. |
| 扔 | Linux内核中的特殊路由。如果一个数据包被扔进路由表,它的行为就像在表中没有找到路由一样。在正常路由中,这意味着数据包的行为就像没有路由一样。在策略路由中,可能会在另一个路由表中找到另一个路由。 Special route in the Linux kernel. If a packet is thrown in a routing table it will behave as if no route was found in the table. In normal routing, this means that the packet will behave as if it had no route. In policy routing, another route might be found in another routing table. |
| 单播 | 单个地址的真实可路由地址。最常见的路线类型。 A real routable address for a single address. The most common type of route. |
| 无法到达 | 这表明我们不知道如何到达无法到达的地址。数据包将被丢弃,并生成 ICMP 主机不可达(类型 3,代码 1)。 This signals an unreachable address that we do not know how to reach. The packets will be discarded and an ICMP Host unreachable (type 3, code 1) will be generated. |
| 联合国规范 | 没有实际意义的未指定地址。 An unspecified address that has no real meaning. |
| 解决方案 | 此地址类型用于将路由查找发送到用户态应用程序,该应用程序将对内核进行查找。这可能需要将丑陋的查找发送到内核外部,或者让应用程序为您执行查找。未在 Linux 中实现。 This address type is used to send route lookups to userland applications which will do the lookup for the kernel. This might be wanted to send ugly lookups to the outside of the kernel, or to have an application do lookups for you. Not implemented in Linux. |
addrtype 匹配是使用 -m addrtype 关键字加载的。完成此操作后,下表中的额外匹配选项将可供使用。
The addrtype match is loaded by using the -m addrtype keyword. When this is done, the extra match options in the following table will be available for usage.
表 10-7。地址类型匹配选项
Table 10-7. Addrtype match options
| 匹配 | --src 类型 |
| 核心 | 2.6 |
| 例子 | iptables -A INPUT -m addrtype --src 类型单播 |
| 解释 | --src-type 匹配选项用于匹配数据包的源地址类型。它可以采用单个地址类型,也可以采用逗号分隔的多个地址类型,例如 --src-type BROADCAST,MULTICAST。匹配选项也可以通过在其前面添加感叹号来反转,例如!--src-类型广播、组播。 The --src-type match option is used to match the source address type of the packet. It can either take a single address type or several separated by coma signs, for example --src-type BROADCAST,MULTICAST. The match option may also be inverted by adding an exclamation sign before it, for example ! --src-type BROADCAST,MULTICAST. |
| 匹配 | --dst 类型 |
| 核心 | 2.6 |
| 例子 | iptables -A INPUT -m addrtype --dst 类型单播 |
| 解释 | --dst-type 的工作方式与 --src-type 完全相同,并且具有相同的语法。唯一的区别是它将根据数据包的目标地址类型来匹配数据包。 The --dst-type works exactly the same way as --src-type and has the same syntax. The only difference is that it will match packets based on their destination address type. |
这些匹配用于 IPSEC AH 和 ESP 协议。IPSEC 用于通过不安全的 Internet 连接创建安全隧道。IPSEC 使用 AH 和 ESP 协议来创建这些安全连接。AH 和 ESP 匹配实际上是两个独立的匹配,但这里都进行了描述,因为它们看起来非常相似,并且都在同一函数中使用。
These matches are used for the IPSEC AH and ESP protocols. IPSEC is used to create secure tunnels over an insecure Internet connection. The AH and ESP protocols are used by IPSEC to create these secure connections. The AH and ESP matches are really two separate matches, but are both described here since they look very much alike, and both are used in the same function.
这里我不会详细描述IPSEC,而是查看以下页面和文档以获取更多信息:
I will not go into detail to describe IPSEC here, instead look at the following pages and documents for more information:
互联网上还有大量与此相关的文档,但您可以根据需要随意查找。
There is also a ton more documentation on the Internet on this, but you are free to look it up as needed.
要使用 AH/ESP 匹配,您需要使用 -m ah 加载 AH 匹配,使用 -m esp 加载 ESP 匹配。
To use the AH/ESP matches, you need to use -m ah to load the AH matches, and -m esp to load the ESP matches.
在 2.2 和 2.4 内核中,Linux 使用称为 FreeS/WAN 的东西来实现 IPSEC,但从 Linux 内核 2.5.47 及更高版本开始,Linux 内核直接实现 IPSEC,无需对内核进行修补。这是对 Linux 上 IPSEC 实现的完全重写。 In 2.2 and 2.4 kernels, Linux used something called FreeS/WAN for the IPSEC implementation, but as of Linux kernel 2.5.47 and up, Linux kernels have a direct implementation of IPSEC that requires no patching of the kernel. This is a total rewrite of the IPSEC implementation on Linux. |
表 10-8。AH 匹配选项
Table 10-8. AH match options
| 匹配 | --ahspi |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p 51 -m ah --ahspi 500 |
| 解释 | 这与 AH 数据包的 AH 安全参数索引 (SPI) 编号相匹配。请注意,您还必须指定协议,因为 AH 运行的协议与标准 TCP、UDP 或 ICMP 协议不同。SPI 编号与源地址、目标地址以及密钥一起使用来创建安全关联 (SA)。SA 唯一标识通往所有主机的每一条 IPSEC 隧道。SPI 用于唯一区分相同两个对等点之间连接的每个 IPSEC 隧道。使用 --ahspi 匹配,我们可以根据数据包的 SPI 来匹配数据包。此匹配可以通过使用 : 符号来匹配整个 SPI 值范围,例如 500:520,这将匹配 SPI 的整个范围。 |
注释匹配用于在 iptables 规则集和内核中添加注释。这可以使您更容易理解规则集并简化调试。例如,您可以添加注释,记录哪个 bash 函数向 netfilter 添加了特定的规则集以及原因。应该注意的是,这实际上并不是一场比赛。使用 -m 注释关键字加载注释匹配。此时,以下选项将可用。
The comment match is used to add comments inside the iptables ruleset and the kernel. This can make it much easier to understand your ruleset and to ease debugging. For example, you could add comments documenting which bash function added specific sets of rules to netfilter, and why. It should be noted that this isn't actually a match. The comment match is loaded using the -m comment keywords. At this point the following options will be available.
connmark 匹配的使用方式与 MARK/mark 目标和匹配组合中的标记匹配非常相似。connmark 匹配用于匹配在与 CONNMARK 目标的连接上设置的标记。只需要一个选项。
The connmark match is used very much the same way as the mark match is in the MARK/mark target and match combination. The connmark match is used to match marks that has been set on a connection with the CONNMARK target. It only takes one option.
要在与第一个创建连接标记的同一数据包上匹配标记,必须在 CONNMARK 目标在第一个数据包上设置标记后使用 connmark 匹配。 To match a mark on the same packet as is the first to create the connection marking, you must use the connmark match after the CONNMARK target has set the mark on the first packet. |
表 10-11。康马克匹配选项
Table 10-11. Connmark match options
| 匹配 | - 标记 |
| 核心 | 2.6 |
| 例子 | iptables -A 输入 -m connmark --mark 12 -j 接受 |
| 解释 | 标记选项用于匹配与连接关联的特定标记。标记匹配必须精确,如果您想在实际匹配任何内容之前从连接标记中过滤掉不需要的标志,您可以指定一个将与连接标记进行与运算的掩码。例如,如果您在连接上将连接标记设置为 33(二进制为 10001),并且只想匹配第一位,则可以运行类似 --mark 1/1 的命令。掩码 (00001) 将被掩码为 10001,因此 10001 && 00001 等于 1,然后与 1 进行匹配。 The mark option is used to match a specific mark associated with a connection. The mark match must be exact, and if you want to filter out unwanted flags from the connection mark before actually matching anything, you can specify a mask that will be anded to the connection mark. For example, if you have a connection mark set to 33 (10001 in binary) on a connection, and want to match the first bit only, you would be able to run something like --mark 1/1. The mask (00001) would be masked to 10001, so 10001 && 00001 equals 1, and then matched against the 1. |
conntrack 匹配是状态匹配的扩展版本,这使得以更精细的方式匹配数据包成为可能。它让您可以查看连接跟踪系统中直接可用的信息,而无需任何“前端”系统,例如状态匹配中的信息。有关连接跟踪系统的更多信息,请查看状态机章节。
The conntrack match is an extended version of the state match, which makes it possible to match packets in a much more granular way. It let's you look at information directly available in the connection tracking system, without any "frontend" systems, such as in the state match. For more information about the connection tracking system, take a look at the The state machine chapter.
conntrack 匹配中有许多不同的匹配,用于连接跟踪系统中的多个不同字段。这些被汇总到下面的列表中。要加载这些匹配项,您需要指定 -m conntrack。
There are a number of different matches put together in the conntrack match, for several different fields in the connection tracking system. These are compiled together into the list below. To load these matches, you need to specify -m conntrack.
表 10-12。连接追踪匹配选项
Table 10-12. Conntrack match options
| 匹配 | --ctstate |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctstate 相关 |
| 解释 | 此匹配用于根据 conntrack 状态来匹配数据包的状态。它用于匹配与原始状态匹配中几乎相同的状态。本场比赛的有效条目是: This match is used to match the state of a packet, according to the conntrack state. It is used to match pretty much the same states as in the original state match. The valid entries for this match are:
这些条目可以一起使用,并用逗号分隔。例如,-m conntrack --ctstate ESTABLISHED,RELATED。也可以通过添加 ! 来反转它。在--ctstate 前面。例如:-m conntrack !--ctstate ESTABLISHED,RELATED,匹配除 ESTABLISHED 和 RELATED 状态之外的所有状态。 The entries can be used together with each other separated by a comma. For example, -m conntrack --ctstate ESTABLISHED,RELATED. It can also be inverted by putting a ! in front of --ctstate. For example: -m conntrack ! --ctstate ESTABLISHED,RELATED, which matches all but the ESTABLISHED and RELATED states. |
| 匹配 | --ctproto |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctproto TCP |
| 解释 | 这与协议匹配,与 --protocol 相同。它可以采用相同类型的值,并使用 ! 进行反转。符号。例如,-m conntrack !--ctproto TCP 匹配除 TCP 协议之外的所有协议。 This matches the protocol, the same as the --protocol does. It can take the same types of values, and is inverted using the ! sign. For example, -m conntrack ! --ctproto TCP matches all protocols but the TCP protocol. |
| 匹配 | --ctorigsrc |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctorigsrc 192.168.0.0/24 |
| 解释 | --ctorigsrc 根据数据包相关的 conntrack 条目的原始源 IP 规范进行匹配。可以使用 ! 来反转匹配。--ctorigsrc 和 IP 规范之间,例如 --ctorigsrc !192.168.0.1。它还可以采用 CIDR 形式的网络掩码,例如 --ctorigsrc 192.168.0.0/24。 --ctorigsrc matches based on the original source IP specification of the conntrack entry that the packet is related to. The match can be inverted by using a ! between the --ctorigsrc and IP specification, such as --ctorigsrc ! 192.168.0.1. It can also take a netmask of the CIDR form, such as --ctorigsrc 192.168.0.0/24. |
| 匹配 | --ctorigdst |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctorigdst 192.168.0.0/24 |
| 解释 | 此匹配的使用方式与 --ctorigsrc 完全相同,只不过它匹配 conntrack 条目的目标字段。它在所有其他方面都具有相同的语法。 This match is used exactly as the --ctorigsrc, except that it matches on the destination field of the conntrack entry. It has the same syntax in all other respects. |
| 匹配 | --ctreplsrc |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctreplsrc 192.168.0.0/24 |
| 解释 | --ctreplsrc 匹配用于根据数据包的原始 conntrack 回复源进行匹配。基本上,这与 --ctorigsrc 相同,但我们匹配即将到来的数据包的预期回复源。当然,该目标可以反转并寻址整个地址范围,就像此类中的先前目标一样。 The --ctreplsrc match is used to match based on the original conntrack reply source of the packet. Basically, this is the same as the --ctorigsrc, but instead we match the reply source expected of the upcoming packets. This target can, of course, be inverted and address a whole range of addresses, just the same as the the previous targets in this class. |
| 匹配 | --ctrepldst |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctrepldst 192.168.0.0/24 |
| 解释 | --ctrepldst 匹配与 --ctreplsrc 匹配相同,不同之处在于它匹配与数据包匹配的 conntrack 条目的回复目标。它也可以反转,并接受范围,就像 --ctreplsrc 匹配一样。 The --ctrepldst match is the same as the --ctreplsrc match, with the exception that it matches the reply destination of the conntrack entry that matched the packet. It too can be inverted, and accept ranges, just as the --ctreplsrc match. |
| 匹配 | --ctstatus |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctstatus 相关 |
| 解释 | 这与连接的状态匹配,如状态机一章中所述。它可以匹配以下状态。 This matches the status of the connection, as described in the The state machine chapter. It can match the following statuses.
这也可以通过使用 ! 来反转。符号。例如 -m conntrack ! --ctstatus ASSURED 将匹配除 ASSURED 之外的所有状态。 This can also be inverted by using the ! sign. For example -m conntrack ! --ctstatus ASSURED which will match all but the ASSURED status. |
| 匹配 | --ctexpire |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m conntrack --ctexpire 100:150 |
| 解释 | 此匹配用于根据 conntrack 条目的到期计时器剩余时间(以秒为单位)来匹配数据包。它可以采用单个值并进行匹配,也可以采用一个范围,如上例所示。也可以使用 ! 来反转它。标志,比如这个 -m conntrack !--ctexpire 100。这将匹配每个到期时间,该时间不正好剩下 100 秒。 This match is used to match on packets based on how long is left on the expiration timer of the conntrack entry, measured in seconds. It can either take a single value and match against, or a range such as in the example above. It can also be inverted by using the ! sign, such as this -m conntrack ! --ctexpire 100. This will match every expiration time, which does not have exactly 100 seconds left to it. |
此匹配用于根据数据包的 DSCP(差分服务代码点)字段进行匹配。这记录在RFC 2638 - 用于互联网 RFC 的两位差分服务架构中。通过指定 -m dscp 显式加载匹配。匹配可以采用两个互斥的选项,如下所述。
This match is used to match on packets based on their DSCP (Differentiated Services Code Point) field. This is documented in the RFC 2638 - A Two-bit Differentiated Services Architecture for the Internet RFC. The match is explicitly loaded by specifying -m dscp. The match can take two mutually exclusive options, described below.
表 10-13。Dscp 匹配选项
Table 10-13. Dscp match options
| 匹配 | --dscp |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m dscp --dscp 32 |
| 解释 | 此选项采用十进制或十六进制形式的 DSCP 值。如果选项值是十进制,则可以写为 32 或 16 等。如果以十六进制书写,则应以 0x 为前缀,如下所示:0x20。也可以使用 ! 来反转它。字符,像这样: -m dscp ! --dscp 32。 This option takes a DSCP value in either decimal or in hex. If the option value is in decimal, it would be written like 32 or 16, et cetera. If written in hex, it should be prefixed with 0x, like this: 0x20. It can also be inverted by using the ! character, like this: -m dscp ! --dscp 32. |
| 匹配 | --dscp 类 |
| 核心 | 2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m dscp --dscp-class BE |
| 解释 | --dscp-class 匹配用于匹配数据包的 DiffServ 类。这些值可以是各种 RFC 中指定的任何 BE、EF、AFxx 或 CSx 类。该匹配可以以与 --dscp 选项相同的方式反转。 The --dscp-class match is used to match on the DiffServ class of a packet. The values can be any of the BE, EF, AFxx or CSx classes as specified in the various RFC's. This match can be inverted just the same way as the --dscp option. |
请注意,--dscp 和 --dscp-class 选项是互斥的,不能相互结合使用。 Please note that the --dscp and --dscp-class options are mutually exclusive and can not be used in conjunction with each other. |
ecn 匹配用于匹配 TCP 和 IPv4 标头中的不同 ECN 字段。RFC 3168 - 将显式拥塞通知 (ECN) 添加到 IP RFC中详细描述了 ECN 。通过在命令行中使用 -m ecn 显式加载匹配。ecn 匹配采用三个不同的选项,如下所述。
The ecn match is used to match on the different ECN fields in the TCP and IPv4 headers. ECN is described in detail in the RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP RFC. The match is explicitly loaded by using -m ecn in the command line. The ecn match takes three different options as described below.
表 10-14。ECN 匹配选项
Table 10-14. Ecn match options
| 匹配 | --ecn |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m ecn --ecn-tcp-cwr |
| 解释 | 该匹配用于匹配 CWR(接收拥塞窗口)位(如果已设置)。CWR 标志设置为通知连接的另一个端点它们已收到 ECE,并且它们已对此作出反应。默认情况下,如果设置了 CWR 位,则匹配,但也可以使用感叹号反转匹配。 This match is used to match the CWR (Congestion Window Received) bit, if it has been set. The CWR flag is set to notify the other endpoint of the connection that they have received an ECE, and that they have reacted to it. Per default this matches if the CWR bit is set, but the match may also be inversed using an exclamation point. |
| 匹配 | --ecn-tcp-ece |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m ecn --ecn-tcp-ece |
| 解释 | 该匹配可用于匹配ECE(ECN-Echo)位。一旦端点之一接收到由路由器设置了 CE 位的数据包,就会设置 ECE。然后,端点在返回的 ACK 数据包中设置 ECE,以通知另一个端点它需要放慢速度。然后,另一个端点发送一个 CWR 数据包,如 --ecn-tcp-cwr 解释中所述。如果设置了 ECE 位,则默认匹配,但可以通过使用感叹号来反转。 This match can be used to match the ECE (ECN-Echo) bit. The ECE is set once one of the endpoints has received a packet with the CE bit set by a router. The endpoint then sets the ECE in the returning ACK packet, to notify the other endpoint that it needs to slow down. The other endpoint then sends a CWR packet as described in the --ecn-tcp-cwr explanation. This matches per default if the ECE bit is set, but may be inversed by using an exclamation point. |
| 匹配 | --ecn-ip-ect |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m ecn --ecn-ip-ect 1 |
| 解释 | --ecn-ip-ect 匹配用于匹配 ECT(支持 ECN 的传输)代码点。ECT 代码点有多种用途。主要用于通过将两个位之一设置为 1 来协商连接是否支持 ECN。路由器还使用 ECT 来指示它们正在经历拥塞,方法是将两个 ECT 代码点设置为 1。ECT 值是所有这些都可以在下面的IP 表中的 ECN 字段中找到。 The --ecn-ip-ect match is used to match the ECT (ECN Capable Transport) codepoints. The ECT codepoints has several types of usage. Mainly, they are used to negotiate if the connection is ECN capable by setting one of the two bits to 1. The ECT is also used by routers to indicate that they are experiencing congestion, by setting both ECT codepoints to 1. The ECT values are all available in the in the ECN Field in IP table below. 可以使用感叹号反转匹配,例如!--ecn-ip-ect 2 将匹配除 ECT(0) 代码点之外的所有 ECN 值。iptables 中的有效值范围是 0-3。有关它们的值,请参阅上表。 The match can be inversed using an exclamation point, for example ! --ecn-ip-ect 2 which will match all ECN values but the ECT(0) codepoint. The valid value range is 0-3 in iptables. See the above table for their values. |
这是极限比赛的修改版本。它不只是设置单个令牌桶,而是为每个目标 IP、源 IP、目标端口和源端口元组设置一个指向令牌桶的哈希表。例如,您可以将其设置为每个 IP 地址每秒最多可以接收 1000 个数据包,或者您可以说特定 IP 地址上的每个服务每秒最多可以接收 200 个数据包。hashlimit 匹配是通过指定 -m hashlimit 关键字来加载的。
This is a modified version of the Limit match. Instead of just setting up a single token bucket, it sets up a hash table pointing to token buckets for each destination IP, source IP, destination port and source port tuple. For example, you can set it up so that every IP address can receive a maximum of 1000 packets per second, or you can say that every service on a specific IP address may receive a maximum of 200 packets per second. The hashlimit match is loaded by specifying the -m hashlimit keywords.
每个使用 hashlimit 匹配的规则都会创建一个单独的哈希表,该哈希表又具有特定的最大大小和最大存储桶数。该哈希表包含单个或多个值的哈希。这些值可以是目标 IP、源 IP、目标端口和源端口中的任何一个和/或全部。然后,每个条目都指向一个充当限制匹配的令牌桶。
Each rule that uses the hashlimit match creates a separate hashtable which in turn has a specific max size and a maximum number of buckets. This hash table contains a hash of either a single or multiple values. The values can be any and/or all of destination IP, source IP, destination port and source port. Each entry then points to a token bucket that works as the limit match.
表 10-16。哈希限制匹配选项
Table 10-16. Hashlimit match options
| 匹配 | --哈希限制 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000/秒 --hashlimit-mode dstip,dstport --hashlimit-name 主机 | ||
| 解释 | --hashlimit 指定每个存储桶的限制。在此示例中,hashlimit 设置为 1000。在此示例中,我们将 hashlimit-mode 设置为 dstip、dstport 和目标 192.168.0.3。因此,对于目标主机上的每个端口或服务,它每秒可以接收 1000 个数据包。这与限制匹配的限制选项设置相同。该限制可以采用/秒、/分钟、/小时或/天后缀。如果未指定后缀,则默认后缀为每秒。 The --hashlimit specifies the limit of each bucket. In this example the hashlimit is set to 1000. In this example, we have set up the hashlimit-mode to be dstip,dstport and destination 192.168.0.3. Hence, for every port or service on the destination host, it can receive 1000 packets per second. This is the same setting as the limit option for the limit match. The limit can take a /sec, /minute, /hour or /day postfix. If no postfix is specified, the default postfix is per second.
| ||
| 匹配 | --哈希限制模式 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.0/16 -m hashlimit --hashlimit 1000/秒 --hashlimit-mode dstip --hashlimit-name 主机 | ||
| 解释 | --hashlimit-mode 选项指定我们应该使用哪些值作为哈希值。在此示例中,我们仅使用 dstip(目标 IP)作为哈希值。因此,在这种情况下,192.168.0.0/16 网络中的每台主机每秒最多接收 1000 个数据包。--hashlimit-mode 的可能值为 dstip(目标 IP)、srcip(源 IP)、dstport(目标端口)和 srcport(源端口)。所有这些也可以用逗号分隔以包含多个哈希值,例如 --hashlimit-mode dstip,dstport。 The --hashlimit-mode option specifies which values we should use as the hash values. In this example, we use only the dstip (destination IP) as the hashvalue. So, each host in the 192.168.0.0/16 network will be limited to receiving a maximum of 1000 packets per second in this case. The possible values for the --hashlimit-mode is dstip (Destination IP), srcip (Source IP), dstport (Destination port) and srcport (Source port). All of these can also be separated by a comma sign to include more than one hashvalue, such as for example --hashlimit-mode dstip,dstport.
| ||
| 匹配 | --hashlimit-名称 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 | ||
| 解释 | 此选项指定此特定哈希可用的名称。可以在/proc/net/ipt_hashlimit 目录中查看。上面的示例可以在 /proc/net/ipt_hashlimit/hosts文件中查看。仅应指定文件名。 This option specifies the name that this specific hash will be available as. It can be viewed inside the /proc/net/ipt_hashlimit directory. The example above would be viewable inside the /proc/net/ipt_hashlimit/hosts file. Only the filename should be specified.
| ||
| 匹配 | --hashlimit-爆发 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 --hashlimit-burst 2000 | ||
| 解释 | 此匹配与 --limit-burst 相同,它设置存储桶的最大大小。每个桶都会有一个突发限制,即单个时间单位内可以匹配的最大数据包数量。有关令牌桶如何工作的示例,请查看Limit match。 This match is the same as the --limit-burst in that it sets the maximum size of the bucket. Each bucket will have a burst limit, which is the maximum amount of packets that can be matched during a single time unit. For an example on how a token bucket works, take a look at the Limit match. | ||
| 匹配 | --hashlimit-htable-大小 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 --hashlimit-htable-size 500 | ||
| 解释 | 这设置了要使用的最大可用存储桶。在此示例中,这意味着最多可以同时打开和活动 500 个端口。 This sets the maximum available buckets to be used. In this example, it means that a maximum of 500 ports can be open and active at the same time. | ||
| 匹配 | --hashlimit-htable-max | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 --hashlimit-htable-max 500 | ||
| 解释 | --hashlimit-htable-max 设置哈希表条目的最大数量。这意味着所有连接,包括暂时不需要任何令牌桶的非活动连接。 The --hashlimit-htable-max sets the maximum number of hashtable entries. This means all of the connections, including the inactive connections that doesn't require any token buckets for the moment. | ||
| 匹配 | --hashlimit-htable-gcinterval | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 --hashlimit-htable-gcinterval 1000 | ||
| 解释 | 垃圾收集功能应该多久运行一次。一般来说这个值应该低于expire值。该值以毫秒为单位测量。如果设置得太低,则会占用不必要的系统资源和处理能力,但如果设置得太高,则可能会使未使用的令牌桶闲置太久,并使其他连接无法进行。在此示例中,垃圾收集器将每秒运行一次。 How often should the garbage collection function be run. Generally speaking this value should be lower than the expire value. The value is measured in milliseconds. If it is set too low it will be taking up unnecessary system resources and processing power, but if it's too high it can leave unused token buckets lying around for too long and leaving other connections impossible. In this example the garbage collector will run every second. | ||
| 匹配 | --hashlimit-htable-过期 | ||
| 核心 | 2.6 | ||
| 例子 | iptables -A INPUT -p tcp --dst 192.168.0.3 -m hashlimit --hashlimit 1000 --hashlimit-mode dstip,dstport --hashlimit-name 主机 --hashlimit-htable-expire 10000 | ||
| 解释 | 该值设置空闲哈希表条目在多长时间后到期。如果存储桶未使用的时间超过此时间,它将过期,并且下一次垃圾收集运行将从哈希表中删除它以及与其相关的所有信息。 This value sets after how long time an idle hashtable entry should expire. If a bucket has been unused for longer than this, it will be expired and the next garbage collection run will remove it from the hashtable, as well as all of the information pertaining to it. |
与其他匹配相比,这是一个相当非正统的匹配,因为它使用了一些特定的语法。match 用于匹配数据包,基于数据包与哪个 conntrack helper 相关。例如,让我们看一下 FTP 会话。打开控制会话,并在控制会话内协商数据会话的端口/连接。ip_conntrack_ftp 帮助程序模块将找到此信息,并在 conntrack 表中创建相关条目。现在,当数据包进入时,我们可以看到它与哪个协议相关,并且我们可以根据使用的帮助程序在规则集中匹配数据包。使用 -m 辅助关键字加载匹配项。
This is a rather unorthodox match in comparison to the other matches, in the sense that it uses a little bit specific syntax. The match is used to match packets, based on which conntrack helper that the packet is related to. For example, let's look at the FTP session. The Control session is opened up, and the ports/connection is negotiated for the Data session within the Control session. The ip_conntrack_ftp helper module will find this information, and create a related entry in the conntrack table. Now, when a packet enters, we can see which protocol it was related to, and we can match the packet in our ruleset based on which helper was used. The match is loaded by using the -m helper keyword.
表 10-17。辅助匹配选项
Table 10-17. Helper match options
| 匹配 | - 帮手 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m 助手 --helper ftp-21 |
| 解释 | --helper 选项用于指定一个字符串值,告诉匹配要匹配哪个 conntrack helper。在基本形式中,它可能看起来像 --helper irc。这是语法开始与正常语法发生变化的地方。我们还可以选择仅根据原始期望捕获的端口来匹配数据包。例如,FTP 控制会话通常通过端口 21 传输,但也可以是端口 954 或任何其他端口。然后我们可以指定应该在哪个端口捕获期望,例如 --helper ftp-954。 The --helper option is used to specify a string value, telling the match which conntrack helper to match. In the basic form, it may look like --helper irc. This is where the syntax starts to change from the normal syntax. We can also choose to only match packets based on which port that the original expectation was caught on. For example, the FTP Control session is normally transferred over port 21, but it may as well be port 954 or any other port. We may then specify upon which port the expectation should be caught on, like --helper ftp-954. |
IP 范围匹配用于匹配 IP 范围,就像 --source 和 --destination 匹配一样。但是,此匹配添加了一种不同类型的匹配,即它能够以从 IP - 到 IP 的方式进行匹配,而 --source 和 --destination 匹配则无法做到这一点。这在某些特定的网络设置中可能需要,并且更加灵活。IP 范围匹配是通过使用 -m iprange 关键字加载的。
The IP range match is used to match IP ranges, just as the --source and --destination matches are able to do as well. However, this match adds a different kind of matching in the sense that it is able to match in the manner of from IP - to IP, which the --source and --destination matches are unable to. This may be needed in some specific network setups, and it is rather a bit more flexible. The IP range match is loaded by using the -m iprange keyword.
表 10-18。IP 范围匹配选项
Table 10-18. IP range match options
| 匹配 | --src-范围 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m iprange --src-range 192.168.1.13-192.168.2.19 |
| 解释 | 这与一系列源 IP 地址匹配。该范围包括从第一个到最后一个的每个 IP 地址,因此上面的示例包括从 192.168.1.13 到 192.168.2.19 的所有内容。也可以通过添加 ! 来反转匹配。上面的例子看起来像 -m iprange !--src-range 192.168.1.13-192.168.2.19,将匹配除指定的之外的每个 IP 地址。 This matches a range of source IP addresses. The range includes every single IP address from the first to the last, so the example above includes everything from 192.168.1.13 to 192.168.2.19. The match may also be inverted by adding an !. The above example would then look like -m iprange ! --src-range 192.168.1.13-192.168.2.19, which would match every single IP address, except the ones specified. |
| 匹配 | --dst-范围 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m iprange --dst-range 192.168.1.13-192.168.2.19 |
| 解释 | --dst-range 的工作方式与 --src-range 匹配完全相同,只不过它匹配目标 IP 而不是源 IP。 The --dst-range works exactly the same as the --src-range match, except that it matches destination IP's instead of source IP's. |
长度匹配用于根据数据包的长度来匹配数据包。这很简单。如果您出于某种奇怪的原因想要限制数据包长度,或者想要阻止类似 ping-of-death 的行为,请使用长度匹配。
The length match is used to match packets based on their length. It is very simple. If you want to limit packet length for some strange reason, or want to block ping-of-death-like behaviour, use the length match.
表 10-19。长度匹配选项
Table 10-19. Length match options
| 匹配 | - 长度 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m 长度 --length 1400:1500 |
| 解释 | 示例 --length 将匹配长度在 1400 到 1500 字节之间的所有数据包。也可以使用 ! 来反转匹配。符号,如下所示:-m 长度!--长度 1400:1500 。它还可以用于仅匹配特定长度,删除 : 符号及以后,如下所示:-m length --length 1400。当然,范围匹配是包含在内的,这意味着它包括之间的所有数据包长度您指定的值。 The example --length will match all packets with a length between 1400 and 1500 bytes. The match may also be inversed using the ! sign, like this: -m length ! --length 1400:1500 . It may also be used to match only a specific length, removing the : sign and onwards, like this: -m length --length 1400. The range matching is, of course, inclusive, which means that it includes all packet lengths in between the values you specify. |
必须使用 -m limit 选项显式加载限制匹配扩展。例如,此匹配可用于对特定规则等进行有限日志记录。例如,您可以使用此匹配来匹配不超过给定值的所有数据包,并且在超过该值后,限制记录有关事件。考虑一个时间限制:您可以限制在特定时间范围内可以匹配特定规则的次数,例如,以减轻 DoS syn 洪水攻击的影响。这是它的主要用法,当然还有更多用法。限制匹配也可以通过添加 ! 来反转。限制匹配前面的标志。然后它会被表示为 -m limit !--limit 5/s。这意味着所有数据包超出限制后都会被匹配。
The limit match extension must be loaded explicitly with the -m limit option. This match can, for example, be used to advantage to give limited logging of specific rules etc. For example, you could use this to match all packets that do not exceed a given value, and after this value has been exceeded, limit logging of the event in question. Think of a time limit: You could limit how many times a certain rule may be matched in a certain time frame, for example to lessen the effects of DoS syn flood attacks. This is its main usage, but there are more usages, of course. The limit match may also be inverted by adding a ! flag in front of the limit match. It would then be expressed as -m limit ! --limit 5/s.This means that all packets will be matched after they have broken the limit.
为了进一步解释限制匹配,它基本上是一个令牌桶过滤器。考虑有一个漏桶,其中桶每个时间单位泄漏 X 个数据包。X 的定义取决于我们获得的匹配数据包数量,因此如果我们获得 3 个数据包,则桶在每个时间单位内泄漏 3 个数据包。--limit 选项告诉我们每个时间单位要重新填充存储桶的数据包数量,而 --limit-burst 选项首先告诉我们存储桶有多大。因此,设置 --limit 3/分钟 --limit-burst 5,然后接收 5 个匹配将清空存储桶。20 秒后,存储桶将重新填充另一个令牌,依此类推,直到再次达到 --limit-burst 或直到它们被使用。
To further explain the limit match, it is basically a token bucket filter. Consider having a leaky bucket where the bucket leaks X packets per time-unit. X is defined depending on how many matching packets we get, so if we get 3 packets, the bucket leaks 3 packets per that time-unit. The --limit option tells us how many packets to refill the bucket with per time-unit, while the --limit-burst option tells us how big the bucket is in the first place. So, setting --limit 3/minute --limit-burst 5, and then receiving 5 matches will empty the bucket. After 20 seconds, the bucket is refilled with another token, and so on until the --limit-burst is reached again or until they get used.
请考虑下面的示例,以进一步解释其外观。
Consider the example below for further explanation of how this may look.
我们用 -m limit --limit 5/秒 --limit-burst 10/秒设置规则。limit-burst令牌桶初始设置为10。每个与规则匹配的数据包都使用一个令牌。
We set a rule with -m limit --limit 5/second --limit-burst 10/second. The limit-burst token bucket is set to 10 initially. Each packet that matches the rule uses a token.
我们得到匹配的数据包,1-2-3-4-5-6-7-8-9-10,全部在 1/1000 秒内完成。
We get packet that matches, 1-2-3-4-5-6-7-8-9-10, all within a 1/1000 of a second.
令牌桶现在是空的。一旦令牌桶为空,符合该规则的数据包将不再匹配该规则,并继续执行下一条规则(如果有),或者命中链策略。
The token bucket is now empty. Once the token bucket is empty, the packets that qualify for the rule otherwise no longer match the rule and proceed to the next rule if any, or hit the chain policy.
每 1/5 秒没有匹配的数据包,令牌计数就会增加 1,最多达到 10。收到 10 个数据包后 1 秒,我们将再次剩下 5 个令牌。
For each 1/5 s without a matching packet, the token count goes up by 1, upto a maximum of 10. 1 second after receiving the 10 packets, we will once again have 5 tokens left.
当然,每收到一个数据包,桶就会清空 1 个令牌。
And of course, the bucket will be emptied by 1 token for each packet it receives.
表 10-20。限制匹配选项
Table 10-20. Limit match options
| 匹配 | - 限制 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m limit --limit 3/小时 |
| 解释 | 这设置了限制匹配的最大平均匹配率。您可以使用数字和可选的时间单位来指定它。目前可识别以下时间单位:/秒/分钟/小时/天。这里的默认值是每小时3个,或者3/小时。这告诉限制匹配在每个时间单位(例如每分钟)允许匹配发生的次数。 |
| 匹配 | --限制爆发 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -m 限制 --limit-burst 5 |
| 解释 | 这是限制匹配的突发限制的设置。它告诉 iptables 当我们启动时或当桶已满时桶中可用的最大令牌数。对于每个到达的数据包,此数字会减 1,直至最低可能值 1。每个时间单位都会按照限制值重新填充存储桶,如 --limit 选项所指定。默认的 --limit-burst 值为 5。要了解其工作原理的简单方法,您可以使用示例Limit-match.txt 单一规则脚本。使用此脚本,您只需以不同的时间间隔和不同的突发数量发送 ping 数据包,即可亲自了解限制规则的工作原理。当超过突发值时,所有回显回复将被阻止,然后每秒由限制值重新填充。 |
MAC(以太网媒体访问控制)匹配可用于根据数据包的 MAC 源地址来匹配数据包。在撰写本文档时,这种匹配有一点限制,但是,将来这可能会更加发展并且可能会更有用。如前所述,此匹配只能用于匹配源 MAC 地址上的数据包。
The MAC (Ethernet Media Access Control) match can be used to match packets based on their MAC source address. As of writing this documentation, this match is a little bit limited, however, in the future this may be more evolved and may be more useful. This match can be used to match packets on the source MAC address only as previously said.
请注意,要使用此模块,我们使用 -m mac 选项显式加载它。我这么说的原因是很多人想知道它是否不应该是 -m mac-source ,它不应该。 Do note that to use this module we explicitly load it with the -m mac option. The reason that I am saying this is that a lot of people wonder if it should not be -m mac-source, which it should not. |
表 10-21。Mac 匹配选项
Table 10-21. Mac match options
| 匹配 | --mac-源 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -m mac --mac-source 00:00:00:00:00:01 |
| 解释 | 此匹配用于根据数据包的 MAC 源地址来匹配数据包。指定的 MAC 地址必须采用XX:XX:XX:XX:XX:XX格式 ,否则不合法。比赛可能会逆转!签名并且看起来像 --mac-source !00:00:00:00:00:01。换句话说,这将颠倒匹配的含义,以便匹配除来自该 MAC 地址的数据包之外的所有数据包。请注意,由于 MAC 地址仅在以太网类型网络上使用,因此此匹配仅可用于以太网接口。MAC 匹配仅在 PREROUTING、FORWARD 和 INPUT 链中有效,在其他链中无效。 |
标记匹配扩展用于根据数据包设置的标记来匹配数据包。标记是一个特殊字段,仅在内核中维护,与数据包在计算机中传输时相关联。不同的内核例程可以使用标记来执行流量整形和过滤等任务。截至目前,Linux 中只有一种设置标记的方法,即 iptables 中的 MARK 目标。以前这是通过 ipchains 中的 FWMARK 目标完成的,这就是为什么人们仍然在高级路由区域中引用 FWMARK 的原因。标记字段当前设置为无符号整数,或 32 位系统上的 4294967296 个可能值。换句话说,您可能在相当长的一段时间内都不会遇到这个限制。
The mark match extension is used to match packets based on the marks they have set. A mark is a special field, only maintained within the kernel, that is associated with the packets as they travel through the computer. Marks may be used by different kernel routines for such tasks as traffic shaping and filtering. As of today, there is only one way of setting a mark in Linux, namely the MARK target in iptables. This was previously done with the FWMARK target in ipchains, and this is why people still refer to FWMARK in advanced routing areas. The mark field is currently set to an unsigned integer, or 4294967296 possible values on a 32 bit system. In other words, you are probably not going to run into this limit for quite some time.
表 10-22。标记匹配选项
Table 10-22. Mark match options
| 匹配 | - 标记 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -t mangle -A 输入 -m 标记 --mark 1 |
| 解释 | 该匹配用于匹配先前已标记的数据包。可以使用 MARK 目标来设置标记,我们将在下一节中讨论。通过 Netfilter 传输的所有数据包都会获得与其关联的特殊标记字段。请注意,此标记字段不会以任何方式在数据包内部或外部传播。它保留在制造它的计算机内。如果标记字段与标记匹配,则匹配。标记字段是一个无符号整数,因此最多可以有 4294967296 个不同的标记。您也可以使用带有 标记的面罩。标记规范将类似于 --mark 1/1。如果指定了掩码,则在实际比较之前将其与指定的标记进行逻辑与运算。 |
多端口匹配扩展可用于指定多个目标端口和端口范围。如果没有这种匹配的可能性,您将不得不使用相同类型的多个规则,只是为了匹配不同的端口。
The multiport match extension can be used to specify multiple destination ports and port ranges. Without the possibility this match gives, you would have to use multiple rules of the same type, just to match different ports.
不能同时使用标准端口匹配和多端口匹配,例如不能写:--sport 1024:63353 -m multiport --dport 21,23,80。这根本行不通。如果您这样做,实际上会发生的情况是 iptables 遵循规则中的第一个元素,并忽略多端口指令。 You can not use both standard port matching and multiport matching at the same time, for example you can't write: --sport 1024:63353 -m multiport --dport 21,23,80. This will simply not work. What in fact happens, if you do, is that iptables honors the first element in the rule, and ignores the multiport instruction. |
表 10-23。多端口匹配选项
Table 10-23. Multiport match options
| 匹配 | --源端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m 多端口 --源端口 22,53,80,110 |
| 解释 | 此匹配匹配多个源端口。最多可以指定 15 个单独的端口。端口必须以逗号分隔,如上例所示。该匹配只能与 -p tcp 或 -p udp 匹配结合使用。它主要是普通的 --source-port 匹配的增强版本。 |
| 匹配 | - 目的端口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m 多端口 --目标端口 22,53,80,110 |
| 解释 | 该匹配用于匹配多个目标端口。它的工作方式与上面提到的源端口匹配完全相同,只是它匹配目标端口。它也有 15 个端口的限制,并且只能与 -p tcp 和 -p udp 结合使用。 |
| 匹配 | - 港口 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m 多端口 --端口 22,53,80,110 |
| 解释 | 此匹配扩展可用于根据数据包的目标端口和源端口来匹配数据包。它的工作方式与上面的 --source-port 和 --destination-port 匹配相同。它最多可以占用 15 个端口,并且只能与 -p tcp 和 -p udp 结合使用。请注意,--port 匹配将仅匹配来自和前往同一端口的数据包,例如,端口 80 到端口 80、端口 110 到端口 110 等。 |
所有者匹配扩展用于根据创建数据包的进程的身份来匹配数据包。所有者可以指定为发出相关命令的用户、组、进程、会话或命令本身的进程 ID。该扩展最初是作为 iptables 用途的示例而编写的。所有者匹配仅在 OUTPUT 链内有效,原因很明显:几乎不可能找到有关从另一端发送数据包的实例的身份的任何信息,或者找到到达真实目的地的中间跃点的信息。即使在 OUTPUT 链内,它也不是很可靠,因为某些数据包可能没有所有者。此类臭名昭著的数据包(除其他外)是不同的 ICMP 响应。ICMP 响应永远不会匹配。
The owner match extension is used to match packets based on the identity of the process that created them. The owner can be specified as the process ID either of the user who issued the command in question, that of the group, the process, the session, or that of the command itself. This extension was originally written as an example of what iptables could be used for. The owner match only works within the OUTPUT chain, for obvious reasons: It is pretty much impossible to find out any information about the identity of the instance that sent a packet from the other end, or where there is an intermediate hop to the real destination. Even within the OUTPUT chain it is not very reliable, since certain packets may not have an owner. Notorious packets of that sort are (among other things) the different ICMP responses. ICMP responses will never match.
表 10-24。所有者匹配选项
Table 10-24. Owner match options
| 匹配 | --cmd-所有者 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 所有者 --cmd-所有者 httpd |
| 解释 | 这是命令所有者匹配,用于根据发送数据包的进程的命令名称进行匹配。示例中匹配httpd。也可以使用感叹号来反转此匹配,例如 -m Owner ! --cmd-所有者 ssh。 This is the command owner match, and is used to match based on the command name of the process that is sending the packet. In the example, httpd is matched. This match may also be inverted by using an exclamation sign, for example -m owner ! --cmd-owner ssh. |
| 匹配 | --uid-所有者 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 所有者 --uid-所有者 500 |
| 解释 | 如果数据包是由给定的用户 ID (UID) 创建的,则此数据包匹配将匹配。这可用于根据创建数据包的人来匹配传出数据包。一种可能的用途是阻止除 root 之外的任何其他用户在防火墙之外打开新连接。另一种可能的用途是阻止除 http 用户之外的所有人从 HTTP 端口发送数据包。 |
| 匹配 | --gid-所有者 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 所有者 --gid-所有者 0 |
| 解释 | 此匹配用于根据组 ID (GID) 匹配所有数据包。这意味着我们根据创建数据包的用户所在的组来匹配所有数据包。这可以用于阻止除网络组中的用户之外的所有用户访问互联网,或者如上所述,仅允许网络组中的成员访问互联网。 http 组创建从 HTTP 端口发出的数据包。 |
| 匹配 | --pid-所有者 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 所有者 --pid-所有者 78 |
| 解释 | 此匹配用于根据负责数据包的进程 ID (PID) 来匹配数据包。此匹配有点难以使用,但一个示例是仅允许 PID 94 从 HTTP 端口发送数据包(当然,如果 HTTP 进程不是线程化的)。或者,我们可以编写一个小脚本,从特定守护进程的 ps 输出中获取 PID,然后为其添加规则。例如,您可以拥有Pid-owner.txt示例中所示的规则。 |
| 匹配 | --sid-所有者 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 所有者 --sid-所有者 100 |
| 解释 | 此匹配用于根据相关程序使用的会话 ID 来匹配数据包。进程的 SID 或会话 ID 的值是进程本身以及源自原始进程的所有进程的值。后者可以是线程,也可以是原始进程的子进程。因此,举例来说,如果我们的 HTTPD 是线程化的(大多数 HTTPD 都是线程化的,例如 Apache 和 Roxen),那么我们所有的 HTTPD 进程都应该与其父进程(原始 HTTPD 进程)具有相同的 SID。为了在示例中展示这一点,我们创建了一个名为Sid-owner.txt的小脚本。该脚本可能每小时左右运行一次,并结合一些额外的代码来检查 HTTPD 是否实际运行,并在必要时重新启动它,然后刷新并重新输入我们的 OUTPUT 链(如果需要)。 |
SMP 内核中的 pid、sid 和命令匹配被破坏,因为它们为每个处理器使用不同的进程列表。不过将来可能会修复 The pid, sid and command matching is broken in SMP kernels since they use different process lists for each processor. It might be fixed in the future however |
数据包类型匹配用于根据数据包的类型来匹配数据包。即,它们是注定给特定的人、每个人还是特定的机器或用户组。这三个组通常称为单播、广播和组播,如TCP/IP 复习章节中所述。使用 -m pkttype 加载匹配。
The packet type match is used to match packets based on their type. I.e., are they destined to a specific person, to everyone or to a specific group of machines or users. These three groups are generally called unicast, broadcast and multicast, as discussed in the TCP/IP repetition chapter. The match is loaded by using -m pkttype.
表 10-25。数据包类型匹配选项
Table 10-25. Packet type match options
| 匹配 | --pkt 类型 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m pkttype --pkt 类型单播 |
| 解释 | --pkt-type match 用于告诉数据包类型匹配要匹配哪种数据包类型。它可以采用单播、广播或多播作为参数,如示例中所示。也可以使用 ! 来反转它。像这样: -m pkttype --pkt-type !广播,它将匹配所有其他数据包类型。 The --pkt-type match is used to tell the packet type match which packet type to match. It can either take unicast , broadcast or multicast as an argument, as in the example. It can also be inverted by using a ! like this: -m pkttype --pkt-type ! broadcast, which will match all other packet types. |
领域匹配用于根据数据包所属的路由领域来匹配数据包。路由领域在 Linux 中用于复杂的路由场景和设置,例如使用 BGP 等时。通过将 -m 领域关键字添加到命令行来加载领域匹配。
The realm match is used to match packets based on the routing realm that they are part of. Routing realms are used in Linux for complex routing scenarios and setups such as when using BGP et cetera. The realm match is loaded by adding the -m realm keyword to the commandline.
Linux 中使用路由领域将路由分类为逻辑路由组。在当今大多数专用路由器中,路由信息库 (RIB) 和转发引擎彼此非常接近。例如在内核内部。由于 Linux 并不是真正的专用路由系统,因此它被迫将其 RIB 和转发信息库 (FIB) 分开。RIB 位于用户空间,FIB 位于内核空间。由于这种分离,在 RIB 中进行快速搜索会占用大量资源。路由领域是 Linux 对此的解决方案,实际上使系统更加灵活和丰富。
A routing realm is used in Linux to classify routes into logical groups of routes. In most dedicated routers today, the Routing Information Base (RIB) and the forwarding engine are very close to eachother. Inside the kernel for example. Since Linux isn't really a dedicated routing system, it has been forced to separate its RIB and Forwarding Information Base (FIB). The RIB lives in userspace and the FIB lives inside kernelspace. Because of this separation, it becomes quite resourceheavy to do quick searches in the RIB. The routing realm is the Linux solution to this, and actually makes the system more flexible and richer.
Linux 领域可以与 BGP 和其他提供大量路由的路由协议一起使用。然后,路由守护程序可以按前缀、aspath 或源对路由进行排序,并将它们放入不同的领域。领域是数字,但也可以通过 /etc/iproute2/rt_realms文件命名。
The Linux realms can be used together with BGP and other routing protocols that delivers huge amounts of routes. The routing daemon can then sort the routes by their prefix, aspath, or source for example, and put them in different realms. The realm is numeric, but can also be named through the /etc/iproute2/rt_realms file.
表 10-26。领域匹配选项
Table 10-26. Realm match options
| 匹配 | - 领域 |
| 核心 | 2.6 |
| 例子 | iptables -A 输出 -m 领域 --realm 4 |
| 解释 | 此选项匹配领域号和可选的掩码。如果这不是数字,它也会尝试从/etc/iproute2/rt_realms文件解析领域 。如果使用命名领域,则不能使用掩码。也可以通过设置感叹号来反转匹配,例如 --realm ! 宇宙。 This option matches the realm number and optionally a mask. If this is not a number, it will also try and resolve the realm from the /etc/iproute2/rt_realms file also. If a named realm is used, no mask may be used. The match may also be inverted by setting an exclamation sign, for example --realm ! cosmos. |
最近的匹配是一个相当庞大和复杂的匹配系统,它允许我们根据之前匹配过的最近事件来匹配数据包。例如,如果我们看到一个传出的 IRC 连接,我们可以将 IP 地址设置到主机列表中,并设置另一条规则,允许在看到原始数据包后 15 秒内从 IRC 服务器返回 identd 请求。
The recent match is a rather large and complex matching system, which allows us to match packets based on recent events that we have previously matched. For example, if we would see an outgoing IRC connection, we could set the IP addresses into a list of hosts, and have another rule that allows identd requests back from the IRC server within 15 seconds of seeing the original packet.
在我们仔细研究匹配选项之前,让我们尝试解释一下它是如何工作的。首先,我们使用几种不同的规则来完成对最近匹配的使用。最近的比赛使用了几个不同的最近事件列表。使用的默认列表是 DEFAULT 列表。我们使用 set 选项在列表中创建一个新条目,因此一旦规则完全匹配(set 选项始终匹配),我们还会在指定的最近列表中添加一个条目。列表条目包含时间戳以及触发设置选项的数据包中使用的源 IP 地址。一旦发生这种情况,我们可以使用一系列不同的最近选项来匹配此信息,以及更新条目时间戳等。
Before we can take a closer look at the match options, let's try and explain a little bit how it works. First of all, we use several different rules to accomplish the use of the recent match. The recent match uses several different lists of recent events. The default list being used is the DEFAULT list. We create a new entry in a list with the set option, so once a rule is entirely matched (the set option is always a match), we also add an entry in the recent list specified. The list entry contains a timestamp, and the source IP address used in the packet that triggered the set option. Once this has happened, we can use a series of different recent options to match on this information, as well as update the entries timestamp, et cetera.
最后,如果我们出于某种原因想要删除列表条目,我们将使用最近匹配中的 --remove 匹配选项来执行此操作。所有使用最近匹配的规则都必须像往常一样加载最近的模块(-m最近)。在我们继续以最近的比赛为例之前,让我们先看一下所有选项。
Finally, if we would for some reason want to remove a list entry, we would do this using the --remove match option from the recent match. All rules using the recent match, must load the recent module (-m recent) as usual. Before we go on with an example of the recent match, let's take a look at all the options.
表 10-27。最近的比赛选项
Table 10-27. Recent match options
| 匹配 | - 姓名 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 最近 --name examplelist |
| 解释 | name 选项给出要使用的列表的名称。默认情况下使用 DEFAULT 列表,如果我们使用多个列表,这可能不是我们想要的。 The name option gives the name of the list to use. Per default the DEFAULT list is used, which is probably not what we want if we are using more than one list. |
| 匹配 | - 放 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 最近 --set |
| 解释 | 这会在命名的最近列表中创建一个新的列表条目,其中包含触发规则的主机的时间戳和源 IP 地址。该匹配将始终返回成功,除非前面有 ! 标志,这种情况下会返回失败。 This creates a new list entry in the named recent list, which contains a timestamp and the source IP address of the host that triggered the rule. This match will always return success, unless it is preceded by a ! sign, in which case it will return failure. |
| 匹配 | --r检查 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 最近 --name examplelist --rcheck |
| 解释 | --rcheck 选项将检查数据包的源 IP 地址是否在指定列表中。如果是,则匹配将返回 true,否则返回 false。可以使用 ! 来反转该选项。符号。在后一种情况下,如果源 IP 地址不在列表中,则返回 true,如果在列表中,则返回 false。 The --rcheck option will check if the source IP address of the packet is in the named list. If it is, the match will return true, otherwise it returns false. The option may be inverted by using the ! sign. In the later case, it will return true if the source IP address is not in the list, and false if it is in the list. |
| 匹配 | - 更新 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m 最近 --name examplelist --update |
| 解释 | 如果源组合在指定列表中可用,并且它还会更新列表中的最后查看时间,则此匹配为 true。通过设置 ! 也可以逆转这场比赛。在比赛前面做标记。例如, ! - 更新。 This match is true if the source combination is available in the specified list and it also updates the last-seen time in the list. This match may also be reversed by setting the ! mark in front of the match. For example, ! --update. |
| 匹配 | - 消除 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name example --remove |
| 解释 | 此匹配将尝试在列表中查找数据包的源地址,如果数据包存在则返回 true。它还将从列表中删除相应的列表条目。该命令也可以与 ! 反转。符号。 This match will try to find the source address of the packet in the list, and returns true if the packet is there. It will also remove the corresponding list entry from the list. The command is also possible to inverse with the ! sign. |
| 匹配 | --秒 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name example --check --seconds 60 |
| 解释 | 此匹配仅与 --check 和 --update 匹配一起有效。--seconds 匹配用于指定自最近列表中更新“上次看到”列以来的时间。如果最后看到的列早于此值(以秒为单位),则匹配返回 false。除此之外,最近的匹配工作正常,因此源地址必须仍然在列表中才能真正返回匹配。 This match is only valid together with the --check and --update matches. The --seconds match is used to specify how long since the "last seen" column was updated in the recent list. If the last seen column was older than this amount in seconds, the match returns false. Other than this the recent match works as normal, so the source address must still be in the list for a true return of the match. |
| 匹配 | --点击次数 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name example --check --hitcount 20 |
| 解释 | --hitcount 匹配必须与 --check 或 --update 匹配一起使用,它将限制匹配仅包含至少已看到 hitcount 数量的数据包的数据包。如果此匹配与 --seconds 匹配一起使用,则将要求在特定时间范围内看到指定的 hitcount 数据包。这场比赛也可以通过添加 ! 来逆转。在比赛前签名。与 --seconds 匹配一起,这意味着在指定的时间范围内可能已经看到了最大数量的数据包。如果两个匹配都相反,则在最后的最短秒数内可能已看到此数量的数据包的最大值。 The --hitcount match must be used together with the --check or --update matches and it will limit the match to only include packets that have seen at least the hitcount amount of packets. If this match is used together with the --seconds match, it will require the specified hitcount packets to be seen in the specific timeframe. This match may also be reversed by adding a ! sign in front of the match. Together with the --seconds match, this means that a maximum of this amount of packets may have been seen during the specified timeframe. If both of the matches are inversed, then a maximum of this amount of packets may have been seen during the last minumum of seconds. |
| 匹配 | --rttl |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name 示例 --check --rttl |
| 解释 | --rttl 匹配用于验证当前数据包的 TTL 值是否与用于设置最近列表中原始条目的原始数据包相同。这可以用来验证人们没有通过利用最近的匹配来欺骗他们的源地址来拒绝其他人访问您的服务器。 The --rttl match is used to verify that the TTL value of the current packet is the same as the original packet that was used to set the original entry in the recent list. This can be used to verify that people are not spoofing their source address to deny others access to your servers by making use of the recent match. |
| 匹配 | --r源 |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name 示例 --rsource |
| 解释 | --rsource match 用于告诉最近的匹配将源地址和端口保存在最近的列表中。这是最近匹配的默认行为。 The --rsource match is used to tell the recent match to save the source address and port in the recent list. This is the default behavior of the recent match. |
| 匹配 | --rdest |
| 核心 | 2.4、2.5 和 2.6 |
| 例子 | iptables -A INPUT -m 最近 --name 示例 --rdest |
| 解释 | --rdest 匹配与 --rsource 匹配相反,它告诉最近的匹配将目标地址和端口保存到最近的列表中。 The --rdest match is the opposite of the --rsource match in that it tells the recent match to save the destination address and port to the recent list. |
我创建了一个关于如何使用最近匹配的小示例脚本,您可以在Recent-match.txt部分中找到该脚本。
I have created a small sample script of how the recent match can be used, which you can find in the Recent-match.txt section.
简而言之,这是 netfilter 中状态引擎的一个糟糕的替代品。该版本在创建时考虑了 http 服务器,但适用于任何 TCP 连接。首先,我们创建了两个名为 http-recent 和 http-recent-final 的链。http-recent 链用于连接的起始阶段,用于实际的数据传输,而 http-recent-final 链用于最后的 FIN/ACK、FIN 握手。
Briefly, this is a poor replacement for the state engine available in netfilter. This version was created with a http server in mind, but will work with any TCP connection. First we have created two chains named http-recent and http-recent-final. The http-recent chain is used in the starting stages of the connection, and for the actual data transmission, while the http-recent-final chain is used for the last and final FIN/ACK, FIN handshake.
这是对内置状态引擎的非常糟糕的替代,并且无法处理状态引擎可以处理的所有可能性。然而,这是一个很好的例子,说明了可以在最近的比赛中做什么而不必太具体。不要在现实环境中使用此示例。它很慢,对特殊情况的处理很糟糕,并且通常只应该用作示例。 This is a very bad replacement for the built in state engine and can not handle all of the possibilities that the state engine can handle. However, it is a good example of what can be done with the recent match without being too specific. Do not use this example in a real world environment. It is slow, handles special cases badly, and should generally never be used more than as an example. 例如,它不处理连接上的关闭端口、异步 FIN 握手(连接方之一关闭,而另一方继续发送数据)等。 For example, it does not handle closed ports on connection, asyncronuous FIN handshake (where one of the connected parties closes down, while the other continues to send data), etc. |
让我们通过示例规则集跟踪数据包。首先,数据包进入 INPUT 链,然后我们将其发送到 http-recent 链。
Let's follow a packet through the example ruleset. First a packet enters the INPUT chain, and we send it to the http-recent chain.
第一个数据包应该是 SYN 数据包,并且不应设置 ACK、FIN 或 RST 位。因此它使用 --tcp-flags SYN,ACK,FIN,RST SYN 行进行匹配。此时,我们使用 -m recent --name httplist --set 行将连接添加到 httplist。最后我们接受了这个数据包。
The first packet should be a SYN packet, and should not have the ACK,FIN or RST bits set. Hence it is matched using the --tcp-flags SYN,ACK,FIN,RST SYN line. At this point we add the connection to the httplist using -m recent --name httplist --set line. Finally we accept the packet.
在第一个数据包之后,我们应该收到一个 SYN/ACK 数据包以确认已收到 SYN 数据包。这可以使用 --tcp-flags SYN,ACK,FIN,RST SYN,ACK 行进行匹配。此时 FIN 和 RST 也应该是非法的。此时,我们使用 -m 最近 --name httplist --update 更新 httplist 中的条目,最后我们接受该数据包。
After the first packet we should receive a SYN/ACK packet to acknowledge that the SYN packet was received. This can be matched using the --tcp-flags SYN,ACK,FIN,RST SYN,ACK line. FIN and RST should be illegal at this point as well. At this point we update the entry in the httplist using -m recent --name httplist --update and finally we ACCEPT the packet.
现在我们应该从连接的原始创建者处获得最终的 ACK 数据包,以确认服务器发送的 SYN/ACK。SYN、FIN 和 RST 在连接点上是非法的,因此该行应类似于 --tcp-flags SYN,ACK,FIN,RST ACK。我们以与上一步完全相同的方式更新列表,并接受它。
By now we should get a final ACK packet, from the original creater of the connection, to acknowledge the SYN/ACK sent by the server. SYN, FIN and RST are illegal at this point of the connection, so the line should look like --tcp-flags SYN,ACK,FIN,RST ACK. We update the list in exactly the same way as in the previous step, and ACCEPT it.
此时就可以开始数据传输了。连接现在不应包含任何 SYN 数据包,但它将包含 ACK 数据包以确认发送的数据包。每次我们看到这样的数据包时,我们都会更新列表并接受这些数据包。
At this point the data transmission can start. The connection should never contain any SYN packet now, but it will contain ACK packets to acknowledge the data packets that are sent. Each time we see any packet like this, we update the list and ACCEPT the packets.
传输可以通过两种方式结束,最简单的是RST数据包。RST 只会重置连接,然后连接就会终止。通过 FIN/ACK,另一个端点用 FIN 进行应答,这将关闭连接,以便 FIN/ACK 的原始源无法再发送任何数据。FIN 的接收者仍然能够发送数据,因此我们将连接发送到“最终”阶段链来处理其余部分。
The transmission can be ended in two ways, the simplest is the RST packet. RST will simply reset the connection and it will die. With FIN/ACK, the other endpoint answers with a FIN, and this closes down the connection so that the original source of the FIN/ACK can no longer send any data. The receiver of the FIN, will still be able to send data, hence we send the connection to a "final" stage chain to handle the rest.
在 http-recent-final 链中,我们检查数据包是否仍在 httplist 中,如果是,则将其发送到 http-recent-final1 链。在该链中,我们从 httplist 中删除连接并将其添加到 http-recent-final 列表中。如果连接已被删除并移至 http-recent-final 列表,我们将数据包发送到 http-recent-final2 链。
In the http-recent-final chain we check if the packet is still in the httplist, and if so, we send it to the http-recent-final1 chain. In that chain we remove the connection from the httplist and add it to the http-recent-final list instead. If the connection has already been removed and moved over to the http-recent-final list, we send te packet to the http-recent-final2 chain.
在最终的 http-recent-final2 链中,我们等待非关闭端完成发送数据,并从其端关闭连接。完成此操作后,连接将被完全删除。
In the final http-recent-final2 chain, we wait for the non-closed side to finish sending its data, and to close the connection from their side as well. Once this is done, the connection is completely removed.
正如您所看到的,最近的列表可能会变得相当复杂,但如果需要的话,它会给您提供大量的可能性。尽管如此,请记住不要重新发明轮子。如果您需要的功能已经实现,请尝试使用它,而不是尝试创建自己的解决方案。
As you can see the recent list can become quite complex, but it will give you a huge set of possibilities if need be. Still, try and remember not to reinvent the wheel. If the ability you need is already implemented, try and use it instead of trying to create your own solution.
状态匹配扩展与内核中的连接跟踪代码结合使用。状态匹配访问来自连接跟踪机的数据包的连接跟踪状态。这使我们能够知道连接处于什么状态,并且适用于几乎所有协议,包括 ICMP 和 UDP 等无状态协议。在所有情况下,连接都会有默认超时,然后将从连接跟踪数据库中删除。需要通过向规则添加 -m state 语句来显式加载此匹配。然后,您将可以访问一场名为“状态”的新比赛。状态匹配的概念在状态机章节中有更全面的介绍,因为它是一个很大的主题。
The state match extension is used in conjunction with the connection tracking code in the kernel. The state match accesses the connection tracking state of the packets from the conntracking machine. This allows us to know in what state the connection is, and works for pretty much all protocols, including stateless protocols such as ICMP and UDP. In all cases, there will be a default timeout for the connection and it will then be dropped from the connection tracking database. This match needs to be loaded explicitly by adding a -m state statement to the rule. You will then have access to one new match called state. The concept of state matching is covered more fully in the The state machine chapter, since it is such a large topic.
表 10-28。状态匹配选项
Table 10-28. State match options
| 匹配 | - 状态 |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -m 状态 --state 相关,已建立 |
| 解释 | 此匹配选项告诉状态匹配数据包必须处于什么状态才能匹配。目前有4种状态可以使用。无效的、既定的、新的和相关的。无效意味着数据包与未知的流或连接关联,并且可能包含错误的数据或标头。ESTABLISHED 表示数据包是已建立的连接的一部分,该连接已在两个方向上看到数据包并且完全有效。NEW 意味着数据包已经或将启动一个新连接,或者它与一个在两个方向上都没有看到数据包的连接关联。最后,RELATED 表示数据包正在启动新连接并与已建立的连接相关联。例如,这可能意味着 FTP 数据传输或与 TCP 或 UDP 连接相关的 ICMP 错误。请注意,NEW 状态不会在试图启动新连接的 TCP 数据包中查找 SYN 位,因此,在我们只有一个防火墙并且不同防火墙之间没有负载平衡的情况下,不应未经修改地使用 NEW 状态。然而,有时这可能会有用。有关如何使用它的更多信息,请阅读状态机章节。 This match option tells the state match what states the packets must be in to be matched. There are currently 4 states that can be used. INVALID, ESTABLISHED, NEW and RELATED. INVALID means that the packet is associated with no known stream or connection and that it may contain faulty data or headers. ESTABLISHED means that the packet is part of an already established connection that has seen packets in both directions and is fully valid. NEW means that the packet has or will start a new connection, or that it is associated with a connection that has not seen packets in both directions. Finally, RELATED means that the packet is starting a new connection and is associated with an already established connection. This could for example mean an FTP data transfer, or an ICMP error associated with a TCP or UDP connection. Note that the NEW state does not look for SYN bits in TCP packets trying to start a new connection and should, hence, not be used unmodified in cases where we have only one firewall and no load balancing between different firewalls. However, there may be times where this could be useful. For more information on how this could be used, read the The state machine chapter. |
tcpmss 匹配用于根据 TCP 中的最大分段大小来匹配数据包。此匹配仅对 SYN 和 SYN/ACK 数据包有效。有关 MSS 值的更完整说明,请参阅TCP 选项 附录、RFC 793 - 传输控制协议和 RFC 1122 - Internet 主机要求 - 通信层文档。该匹配使用 -m tcpmss 加载,并且仅采用一个选项。
The tcpmss match is used to match a packet based on the Maximum Segment Size in TCP. This match is only valid for SYN and SYN/ACK packets. For a more complete explanation of the MSS value, see the TCP options appendix, the RFC 793 - Transmission Control Protocol and the RFC 1122 - Requirements for Internet Hosts - Communication Layers documents. This match is loaded using -m tcpmss and takes only one option.
表 10-29。Tcpmss 匹配选项
Table 10-29. Tcpmss match options
| 匹配 | --mss |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp --tcp-flags SYN、ACK、RST SYN -m tcpmss --mss 2000:2500 |
| 解释 | --mss 选项告诉 tcpmss 匹配要匹配的最大段大小。这可以是单个特定的 MSS 值,也可以是由 : 分隔的一系列 MSS 值。该值也可以像往常一样使用 ! 标志,如下例所示: The --mss option tells the tcpmss match which Maximum Segment Sizes to match. This can either be a single specific MSS value, or a range of MSS values separated by a :. The value may also be inverted as usual using the ! sign, as in the following example: -m TCPMSS!--MSS 2000:2500 -m tcpmss ! --mss 2000:2500 此示例将匹配除 2000 到 2500 范围内的值之外的所有 MSS 值。 This example will match all MSS values, except for values in the range 2000 through 2500. |
TOS 匹配可用于根据 TOS 字段来匹配数据包。TOS 代表服务类型,由 8 位组成,位于 IP 标头中。通过将 -m 添加到规则中来显式加载此匹配项。TOS 通常用于通知中间主机流及其内容的优先级(实际上并非如此,但它通知流的任何特定要求,例如必须尽快发送,或者需要能够发送尽可能多的有效负载)。不同的路由器和管理员如何处理这些值取决于。大多数人根本不在乎,而另一些人则尽最大努力对有问题的数据包及其提供的数据做一些好事。
The TOS match can be used to match packets based on their TOS field. TOS stands for Type Of Service, consists of 8 bits, and is located in the IP header. This match is loaded explicitly by adding -m tos to the rule. TOS is normally used to inform intermediate hosts of the precedence of the stream and its content (it doesn't really, but it informs of any specific requirements for the stream, such as it having to be sent as fast as possible, or it needing to be able to send as much payload as possible). How different routers and administrators deal with these values depends. Most do not care at all, while others try their best to do something good with the packets in question and the data they provide.
表 10-30。Tos 匹配选项
Table 10-30. Tos match options
| 匹配 | --tos |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输入 -p tcp -m tos --tos 0x16 |
| 解释 | 该匹配的使用方法如上所述。它可以根据 TOS 字段及其值来匹配数据包。这可以与 Linux 中的 iproute2 和高级路由功能一起使用,以标记数据包以供以后使用。该匹配采用十六进制或数字值作为选项,或者可能是“iptables -m tos -h”产生的名称之一。在撰写本文时,它包含以下命名值:Minimize-Delay 16 (0x10)、Maximize-Throughput 8 (0x08)、Maximize-Reliability 4 (0x04)、Minimize-Cost 2 (0x02) 和 Normal-Service 0 ( 0x00)。最小化延迟意味着最小化数据包通过的延迟 - 需要这样做的标准服务示例包括 telnet、SSH 和 FTP 控制。吞吐量最大化意味着找到一条允许尽可能大吞吐量的路径 - 标准协议是 FTP 数据。可靠性最大化意味着最大化连接的可靠性并使用尽可能可靠的线路 - 几个典型的例子是 BOOTP 和 TFTP。Minimize-Cost 意味着最小化数据包通过每个链路到达客户端或服务器的成本;例如,找到行驶成本最低的路线。使用此协议的普通协议的示例是 RTSP(实时流控制协议)和其他流视频/无线电协议。最后,正常服务意味着没有特殊需求的任何正常协议。可靠性最大化意味着最大化连接的可靠性并使用尽可能可靠的线路 - 几个典型的例子是 BOOTP 和 TFTP。Minimize-Cost 意味着最小化数据包通过每个链路到达客户端或服务器的成本;例如,找到行驶成本最低的路线。使用此协议的普通协议的示例是 RTSP(实时流控制协议)和其他流视频/无线电协议。最后,正常服务意味着没有特殊需求的任何正常协议。可靠性最大化意味着最大化连接的可靠性并使用尽可能可靠的线路 - 几个典型的例子是 BOOTP 和 TFTP。Minimize-Cost 意味着最小化数据包通过每个链路到达客户端或服务器的成本;例如,找到行驶成本最低的路线。使用此协议的普通协议的示例是 RTSP(实时流控制协议)和其他流视频/无线电协议。最后,正常服务意味着没有特殊需求的任何正常协议。使用此协议的普通协议的示例是 RTSP(实时流控制协议)和其他流视频/无线电协议。最后,正常服务意味着没有特殊需求的任何正常协议。使用此协议的普通协议的示例是 RTSP(实时流控制协议)和其他流视频/无线电协议。最后,正常服务意味着没有特殊需求的任何正常协议。 |
TTL 匹配用于根据 IP 标头中的 TTL(生存时间)字段来匹配数据包。TTL 字段包含 8 位数据,每次由客户端和接收主机之间的中间主机处理时都会递减一次。如果 TTL 达到 0,则会向发送数据包的一方发送 ICMP 类型 11 代码 0(传输期间 TTL 等于 0)或代码 1(重组期间 TTL 等于 0)并通知其问题。此匹配仅用于根据数据包的 TTL 进行匹配,不会更改任何内容。顺便说一句,后者适用于所有类型的比赛。要加载此匹配,您需要向规则添加 -m ttl。
The TTL match is used to match packets based on their TTL (Time To Live) field residing in the IP headers. The TTL field contains 8 bits of data and is decremented once every time it is processed by an intermediate host between the client and recipient host. If the TTL reaches 0, an ICMP type 11 code 0 (TTL equals 0 during transit) or code 1 (TTL equals 0 during reassembly) is transmitted to the party sending the packet and informing it of the problem. This match is only used to match packets based on their TTL, and not to change anything. The latter, incidentally, applies to all kinds of matches. To load this match, you need to add an -m ttl to the rule.
表 10-31。Ttl 匹配选项
Table 10-31. Ttl match options
| 匹配 | --ttl-eq |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m ttl --ttl-eq 60 |
| 解释 | 该匹配选项用于指定精确匹配的 TTL 值。它采用一个数值并与数据包中的该值相匹配。没有反转,也没有其他细节可以匹配。例如,它可以用于调试您的本地网络 - 例如,连接到 Internet 上的主机时出现问题的 LAN 主机 - 或者查找特洛伊木马的可能入口等。但是,其用途相对有限;它的用处实际上取决于你的想象力。一个例子是查找默认 TTL 值错误的主机(可能是由于 TCP/IP 堆栈实施不当,或者仅仅是配置错误)。 |
| 匹配 | --ttl-gt |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m ttl --ttl-gt 64 |
| 解释 | 此匹配选项用于匹配任何大于指定值的 TTL。该值可以在 0 到 255 之间,且匹配不能反转。例如,它可以用于匹配任何大于特定值的 TTL,然后强制它们达到标准化值。这可以用来克服 ISP 的一些简单形式的间谍活动,以查明您是否在防火墙后面运行多台计算机,违反他们的策略。 |
| 匹配 | --ttl-lt |
| 核心 | 2.3、2.4、2.5 和 2.6 |
| 例子 | iptables -A 输出 -m ttl --ttl-lt 64 |
| 解释 | --ttl-lt 匹配用于匹配任何小于指定值的 TTL。它与 --ttl-gt 匹配几乎相同,但如前所述;它与较小的 TTL 匹配。它也可以以与 --ttl-gt 匹配相同的方式使用,或者简单地均匀化离开网络的数据包。 |
不干净的匹配不需要任何选项,并且只需要在您想要使用它时显式加载它即可。请注意,此选项被视为实验性的,可能无法始终有效,也不会处理所有不干净的包或问题。不干净的匹配尝试匹配看起来格式错误或异常的数据包,例如具有错误标头或校验和的数据包等。例如,这可以用于删除连接并检查坏流;但是您应该意识到这可能会破坏法律关系。
The unclean match takes no options and requires no more than explicitly loading it when you want to use it. Note that this option is regarded as experimental and may not work at all times, nor will it take care of all unclean packages or problems. The unclean match tries to match packets that seem malformed or unusual, such as packets with bad headers or checksums and so on. This could be used to DROP connections and to check for bad streams, for example; however you should be aware that it could possibly break legal connections.
上一章介绍了 iptables 中可以使用的匹配项以及它们的功能。如您所见,iptables 和 netfilter 的匹配能力非常完善且非常灵活。下一章将详细讨论目标以及它们能够做什么。您将在该章中注意到 Linux 防火墙的功能。
The last chapter has been about the matches that can be used in iptables and what they are capable of doing. The matching capability of iptables and netfilter is extremely well developed and very flexible as you have seen. The next chapter will discuss the targets in detail and what they are able to do. You will notice in that chapter as well the capabilities of Linux firewalling.
目标/跳转告诉规则如何处理与规则的匹配部分完全匹配的数据包。有几个基本目标,即 ACCEPT 和 DROP 目标,我们将首先处理它们。然而,在此之前,让我们简要了解一下跳跃是如何完成的。
The target/jumps tells the rule what to do with a packet that is a perfect match with the match section of the rule. There are a couple of basic targets, the ACCEPT and DROP targets, which we will deal with first. However, before we do that, let us have a brief look at how a jump is done.
跳转规范的完成方式与目标定义中的方式完全相同,只是它需要跳转到同一表内的链。要跳转到某个特定的链,当然前提是该链存在。正如我们已经解释过的,用户定义的链是使用 -N 命令创建的。例如,假设我们在过滤器表中创建一个名为 tcp_packets 的链,如下所示:
The jump specification is done in exactly the same way as in the target definition, except that it requires a chain within the same table to jump to. To jump to a specific chain, it is of course a prerequisite that that chain exists. As we have already explained, a user-defined chain is created with the -N command. For example, let's say we create a chain in the filter table called tcp_packets, like this:
iptables -N tcp_packets
iptables -N tcp_packets
然后我们可以像这样添加一个跳转目标:
We could then add a jump target to it like this:
iptables -A 输入 -p tcp -j tcp_packets
iptables -A INPUT -p tcp -j tcp_packets
然后我们将从 INPUT 链跳转到 tcp_packets 链并开始遍历该链。当/如果我们到达该链的末尾,我们就会被丢弃回 INPUT 链,并且数据包开始从跳到另一条链(在本例中为 tcp_packets)的下一级规则开始遍历。如果一个数据包在其中一个子链中被接受,那么它也将在超集链中被接受,并且它不会进一步遍历任何超集链。但是,请注意,数据包将以正常方式遍历其他表中的所有其他链。有关表和链遍历的更多信息,请参阅表和链的遍历 一章。
We would then jump from the INPUT chain to the tcp_packets chain and start traversing that chain. When/If we reach the end of that chain, we get dropped back to the INPUT chain and the packet starts traversing from the rule one step below where it jumped to the other chain (tcp_packets in this case). If a packet is ACCEPTed within one of the sub chains, it will be ACCEPT'ed in the superset chain also and it will not traverse any of the superset chains any further. However, do note that the packet will traverse all other chains in the other tables in a normal fashion. For more information on table and chain traversing, see the Traversing of tables and chains chapter.
另一方面,目标指定对相关数据包采取的操作。例如,我们可以根据我们想要执行的操作来丢弃或接受数据包。我们还可能想要采取许多其他行动,我们将在本节中进一步描述。可以说,跳跃到目标可能会产生不同的结果。某些目标将导致数据包停止遍历该特定链和上级链,如上所述。此类规则的好例子是 DROP 和 ACCEPT。被停止的规则将不会通过链中或上级链中的任何规则。其他目标可能会对数据包采取操作,之后数据包将继续通过其余规则。LOG、ULOG 和 TOS 目标就是一个很好的例子。这些目标可以记录数据包,破坏它们,然后将它们传递给同一组链中的其他规则。例如,我们可能希望这样做,以便我们另外可以修改特定数据包/流的 TTL 和 TOS 值。一些目标将接受额外的选项(使用什么 TOS 值等),而其他目标则不一定需要任何选项 - 但如果我们愿意,我们可以包含它们(日志前缀、伪装端口等)。当我们浏览目标描述时,我们将尝试涵盖所有这些要点。让我们看看有哪些类型的目标。而其他人不一定需要任何选项 - 但如果我们愿意,我们可以包括它们(记录前缀、伪装端口等)。当我们浏览目标描述时,我们将尝试涵盖所有这些要点。让我们看看有哪些类型的目标。而其他人不一定需要任何选项 - 但如果我们愿意,我们可以包括它们(记录前缀、伪装端口等)。当我们浏览目标描述时,我们将尝试涵盖所有这些要点。让我们看看有哪些类型的目标。
Targets on the other hand specify an action to take on the packet in question. We could for example, DROP or ACCEPT the packet depending on what we want to do. There are also a number of other actions we may want to take, which we will describe further on in this section. Jumping to targets may incur different results, as it were. Some targets will cause the packet to stop traversing that specific chain and superior chains as described above. Good examples of such rules are DROP and ACCEPT. Rules that are stopped, will not pass through any of the rules further on in the chain or in superior chains. Other targets, may take an action on the packet, after which the packet will continue passing through the rest of the rules. A good example of this would be the LOG, ULOG and TOS targets. These targets can log the packets, mangle them and then pass them on to the other rules in the same set of chains. We might, for example, want this so that we in addition can mangle both the TTL and the TOS values of a specific packet/stream. Some targets will accept extra options (What TOS value to use etc), while others don't necessarily need any options - but we can include them if we want to (log prefixes, masquerade-to ports and so on). We will try to cover all of these points as we go through the target descriptions. Let us have a look at what kinds of targets there are.
这个目标不需要更多的选择。一旦数据包的匹配规范完全满足,并且我们指定 ACCEPT 作为目标,规则就会被接受,并且不会继续遍历当前链或同一个表中的任何其他链。但请注意,在一个链中接受的数据包可能仍会穿过其他表中的链,并且仍可能被丢弃在那里。这个目标没有什么特别之处,它不需要也不可能向目标添加选项。要使用此目标,我们只需指定 -j ACCEPT。
This target needs no further options. As soon as the match specification for a packet has been fully satisfied, and we specify ACCEPT as the target, the rule is accepted and will not continue traversing the current chain or any other ones in the same table. Note however, that a packet that was accepted in one chain might still travel through chains within other tables, and could still be dropped there. There is nothing special about this target whatsoever, and it does not require, nor have the possibility of, adding options to the target. To use this target, we simply specify -j ACCEPT.
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
CLASSIFY 目标可用于对数据包进行分类,这种方式可由多个不同的 qdisc(队列规则)使用。例如,atm、cbq、dsmark、pfifo_fast、htb 和 prio qdisc。有关 qdisc 和流量控制的更多信息,请访问Linux 高级路由和流量控制操作方法网页。
The CLASSIFY target can be used to classify packets in such a way that can be used by a couple of different qdiscs (Queue Disciplines). For example, atm, cbq, dsmark, pfifo_fast, htb and the prio qdiscs. For more information about qdiscs and traffic controlling, visit the Linux Advanced Routing and Traffic Control HOW-TO webpage.
CLASSIFY 目标仅在 mangle 表的 POSTROUTING 链中有效。
The CLASSIFY target is only valid in the POSTROUTING chain of the mangle table.
表 11-1。对目标选项进行分类
Table 11-1. CLASSIFY target options
| 选项 | --设置类 |
| 例子 | iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j CLASSIFY --set-class 20:10 |
| 解释 | CLASSIFY 目标仅采用一个参数,即 --set-class。这告诉目标如何对数据包进行分类。该类采用 2 个由逗号分隔的值,如 MAJOR:MINOR。再次强调,如果您想了解更多相关信息,请查看Linux 高级路由和流量控制 HOW-TO网页。 |
在 Linux 内核 2.5 和 2.6 下运行。 Works under Linux kernel 2.5 and 2.6. |
CLUSTERIP 目标用于创建简单的节点集群,以循环方式响应相同的 IP 和 MAC 地址。这是一种简单的集群形式,您可以在参与集群的所有主机上设置虚拟 IP (VIP),然后在应该响应请求的每台主机上使用 CLUSTERIP。CLUSTERIP 匹配不需要特殊的负载平衡硬件或机器,它只是在机器集群的每个主机部分上完成工作。它是一个非常简单的集群解决方案,不适合大型和复杂的集群,也没有内置的心跳处理,但它应该可以轻松地实现为一个简单的脚本。
The CLUSTERIP target is used to create simple clusters of nodes answering to the same IP and MAC address in a round robin fashion. This is a simple form of clustering where you set up a Virtual IP (VIP) on all hosts participating in the cluster, and then use the CLUSTERIP on each host that is supposed to answer the requests. The CLUSTERIP match requires no special load balancing hardware or machines, it simply does its work on each host part of the cluster of machines. It is a very simple clustering solution and not suited for large and complex clusters, neither does it have built in heartbeat handling, but it should be easily implemented as a simple script.
集群中的所有服务器都使用通用的多播 MAC 作为 VIP,然后在 CLUSTERIP 目标中使用特殊的哈希算法来确定集群参与者中的哪些人应该响应每个连接。组播 MAC 是以 01:00:5e 作为前 24 位开始的 MAC 地址。多播 MAC 的示例为 01:00:5e:00:00:20。VIP 可以是任何 IP 地址,但在所有主机上也必须相同。
All servers in the cluster uses a common Multicast MAC for a VIP, and then a special hash algorithm is used within the CLUSTERIP target to figure out who of the cluster participants should respond to each connection. A Multicast MAC is a MAC address starting with 01:00:5e as the first 24 bits. an example of a Multicast MAC would be 01:00:5e:00:00:20. The VIP can be any IP address, but must be the same on all hosts as well.
请记住,CLUSTERIP 可能会破坏 SSH 等协议。连接将正确进行,但如果您在同一时间再次尝试连接到同一台主机,您可能会使用不同的密钥集连接到集群中的另一台计算机,因此您的 ssh 客户端可能会拒绝连接或给出错误。因此,这对于某些协议来说不能很好地工作,并且添加可用于维护和管理的单独地址可能是一个好主意。另一种解决方案是在参与集群的所有主机上使用相同的 SSH 密钥。 Remember that the CLUSTERIP might break protocols such as SSH et cetera. The connection will go through properly, but if you try the same time again to the same host, you might be connected to another machine in the cluster, with a different keyset, and hence your ssh client might refuse to connect or give you errors. For this reason, this will not work very well with some protocols, and it might be a good idea to add separate addresses that can be used for maintenance and administration. Another solution is to use the same SSH keys on all hosts participating in the cluster. |
集群可以通过三种hash模式进行负载均衡。第一个只有源 IP (sourceip),第二个是源 IP 和源端口 (sourceip-sourceport),第三个是源 IP、源端口和目标端口 (sourceip-sourceport-destport)。第一个可能是一个好主意,您需要记住连接之间的状态,例如带有购物车的网络服务器可以保存连接之间的状态,这种负载平衡可能会变得有点不均匀——不同的机器可能会获得更高的负载比其他的等等——因为来自同一源 IP 的连接将转到同一服务器。当您希望负载平衡更加均匀,并且不必在每个服务器上的连接之间保留状态时,sourceip-sourceport 哈希可能是一个好主意。例如,一个带有简单搜索引擎的大型信息网页可能是一个好主意。第三个也是最后一个哈希模式,sourceip-sourceport-destport,可能是一个好主意,如果您的主机正在运行多个服务,并且不需要在连接之间保留任何状态。例如,这可能是同一主机上的简单 ntp、dns 和 www 服务器。因此,到每个新目的地的每个连接都将被“重新协商”——实际上没有进行任何协商,它基本上只是一个循环系统,每个主机都会收到一个连接。例如,这可能是同一主机上的简单 ntp、dns 和 www 服务器。因此,到每个新目的地的每个连接都将被“重新协商”——实际上没有进行任何协商,它基本上只是一个循环系统,每个主机都会收到一个连接。例如,这可能是同一主机上的简单 ntp、dns 和 www 服务器。因此,到每个新目的地的每个连接都将被“重新协商”——实际上没有进行任何协商,它基本上只是一个循环系统,每个主机都会收到一个连接。
The cluster can be loadbalanced with three kinds of hashmodes. The first one is only source IP (sourceip), the second is source IP and source port (sourceip-sourceport) and the third one is source IP, source port and destination port (sourceip-sourceport-destport). The first one might be a good idea where you need to remember states between connections, for example a webserver with a shopping cart that keeps state between connections, this load-balancing might become a little bit uneven -- different machines might get a higher loads than others, et cetera -- since connections from the same source IP will go to the same server. The sourceip-sourceport hash might be a good idea where you want to get the load-balancing a little bit more even, and where state does not have to be kept between connections on each server. For example, a large informational webpage with perhaps a simple search engine might be a good idea here. The third and last hashmode, sourceip-sourceport-destport, might be a good idea where you have a host with several services running that does not require any state to be preserved between connections. This might for example be a simple ntp, dns and www server on the same host. Each connection to each new destination would hence be "renegotiated" -- actually no negotiation goes on, it is basically just a round robin system and each host receives one connection each.
每个 CLUSTERIP 集群 根据集群的 VIP在/proc/net/ipt_CLUSTERIP目录中获取一个单独的文件。例如,如果 VIP 是 192.168.0.5,您可以 cat /proc/net/ipt_CLUSTERIP/192.168.0.5 来查看该计算机正在响应哪些节点。要使机器应答另一台机器(假设为节点 2),请使用 echo "+2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5 添加它。要删除它,请运行 echo "-2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5。
Each CLUSTERIP cluster gets a separate file in the /proc/net/ipt_CLUSTERIP directory, based on the VIP of the cluster. If the VIP is 192.168.0.5 for example, you could cat /proc/net/ipt_CLUSTERIP/192.168.0.5 to see which nodes this machine is answering for. To make the machine answer for another machine, lets say node 2, add it using echo "+2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5. To remove it, run echo "-2" >> /proc/net/ipt_CLUSTERIP/192.168.0.5.
表 11-2。CLUSTERIP 目标选项
Table 11-2. CLUSTERIP target options
| 选项 | - 新的 |
| 例子 | iptables -A 输入 -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new ... |
| 解释 | 这将创建一个新的 CLUSTERIP 条目。它必须在 VIP 的第一条规则上设置,并用于创建新集群。如果您有多个规则连接到同一 CLUSTERIP,则可以在对同一 VIP 的任何辅助引用中省略 --new 关键字。 |
| 选项 | --哈希模式 |
| 例子 | iptables -A INPUT -p tcp -d 192.168.0.5 --dport 443 -j CLUSTERIP --new --hashmode sourceip ... |
| 解释 | --hashmode 关键字指定应创建的哈希类型。hashmode 可以是以下三种中的任意一种。 The --hashmode keyword specifies the kind of hash that should be created. The hashmode can be any of the following three.
上面已经对哈希模式进行了广泛的解释。基本上,sourceip 将在连接之间提供更好的性能和更简单的状态,但不会在机器之间提供良好的负载平衡。sourceip-sourceport 的散列速度稍慢,并且不太适合维护连接之间的状态,但会提供更好的负载平衡属性。最后一个可能会创建非常慢的散列,消耗大量内存,但另一方面也会创建非常好的负载平衡属性。 The hashmodes has been extensively explained above. Basically, sourceip will give better performance and simpler states between connections, but not as good load-balancing between the machines. sourceip-sourceport will give a slightly slower hashing and not as good to maintain states between connections, but will give better load-balancing properties. The last one may create very slow hashing that consumes a lot of memory, but will on the other hand also create very good load-balancing properties. |
| 选项 | --clustermac |
| 例子 | iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode sourceip --clustermac 01:00:5e:00:00:20 ... |
| 解释 | 集群正在侦听新连接的 MAC 地址。这是所有主机都在侦听的共享多播 MAC 地址。对此的更深入解释请参见上文。 |
| 选项 | --总节点数 |
| 例子 | iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode sourceip --clustermac 01:00:5e:00:00:20 --total-nodes 2 ... |
| 解释 | --total-nodes 关键字指定参与集群的主机数量以及将响应请求的主机数量。请参阅上文以获得更深入的解释。 |
| 选项 | --本地节点 |
| 例子 | iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode sourceip --clustermac 01:00:5e:00:00:20 --total-nodes 2 --local-节点1 |
| 解释 | 这是该机器在集群中的编号。集群以循环方式应答,因此一旦与集群建立新连接,下一台机器就会应答,然后是下一台机器,依此类推。 |
| 选项 | --哈希初始化 |
| 例子 | iptables -A INPUT -p tcp -d 192.168.0.5 --dport 80 -j CLUSTERIP --new --hashmode sourceip --clustermac 01:00:5e:00:00:20 --hash-init 1234 |
| 解释 | 指定用于哈希初始化的随机种子。 |
此目标违反了RFC 1812 - IP 版本 4 路由器RFC 的要求,因此请警惕可能出现的任何问题。具体来说,第 3.3.2 节指定路由器绝不能信任声称它正在使用多播 MAC 的另一台主机或路由器。 This target is in violation of the RFC 1812 - Requirements for IP Version 4 Routers RFC, so be wary of any problems that may arise. Specifically, section 3.3.2 which specifies that a router must never trust another host or router that says that it is using a multicast mac. |
在最新的 Linux 2.6 内核下工作,标记为实验性的。 Works under late Linux 2.6 kernels, marked experimental. |
CONNMARK 目标用于在整个连接上设置标记,与 MARK 目标的方式非常相似。然后它可以与 connmark match 一起使用来匹配将来的连接。例如,假设我们在标头中看到特定模式,并且我们不想仅标记该数据包,而是标记整个连接。在这种情况下,CONNMARK 目标是一个完美的解决方案。
The CONNMARK target is used to set a mark on a whole connection, much the same way as the MARK target does. It can then be used together with the connmark match to match the connection in the future. For example, say we see a specific pattern in a header, and we don't want to mark just that packet, but the whole connection. The CONNMARK target is a perfect solution in that case.
CONNMARK 目标在所有链和所有表中都可用,但请记住 nat 表仅由连接中的第一个数据包遍历,因此如果您尝试将其用于第一个数据包之后的后续数据包,则 CONNMARK 目标将不起作用在这里。它可以采用四种不同选项之一,如下所示。
The CONNMARK target is available in all chains and all tables, but remember that the nat table is only traversed by the first packet in a connection, so the CONNMARK target will have no effect if you try to use it for subsequent packets after the first one in here. It can take one of four different options as seen below.
表 11-3。CONNMARK 目标选项
Table 11-3. CONNMARK target options
| 选项 | --设置标记 |
| 例子 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j CONNMARK --set-mark 4 |
| 解释 | 此选项在连接上设置标记。该标记可以是 unsigned long int,这意味着 0 到 4294967295l 之间的值是有效的。每个位也可以通过执行 --set-mark 12/8 来屏蔽。这将仅允许将掩码中的位设置在标记中的所有位之外。在此示例中,仅设置第 4 位,而不是第 3 位。12 转换为二进制的 1100,8 转换为 1000,并且只允许设置掩码中设置的位。因此,只有第 4 位(即 8 位)被设置在实际标记中。 |
| 选项 | --保存标记 |
| 例子 | iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --save-mark |
| 解释 | --save-mark 目标选项用于将数据包标记保存到连接标记中。例如,如果您使用 MARK 目标设置了数据包标记,则可以移动此标记以使用 --save-mark 匹配来标记整个连接。还可以使用下面进一步描述的 --mask 选项来屏蔽该标记。 |
| 选项 | --恢复标记 |
| 例子 | iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --restore-mark |
| 解释 | 该目标选项根据 CONNMARK 定义的连接标记恢复数据包标记。还可以使用 --mask 选项定义掩码,如下所示。如果设置了掩码,则仅设置掩码选项。请注意,此目标选项仅在 mangle 表中使用有效。 |
| 选项 | - 面具 |
| 例子 | iptables -t mangle -A PREROUTING --dport 80 -j CONNMARK --restore-mark --mask 12 |
| 解释 | --mask 选项必须与 --save-mark 和 --restore-mark 选项配合使用。--mask 选项指定应应用于其他两个选项将给出的标记值的 and-mask。例如,如果上例中恢复的标记为 15,则意味着该标记的二进制为 1111,而掩码为 1100。1111 和 1100 等于 1100。 |
运行在 Linux 内核 2.6 下。 Works under Linux kernel 2.6. |
CONNSECMARK 目标将 SELinux 安全上下文标记设置为数据包标记或从数据包标记设置 SELinux 安全上下文标记。有关 SELinux 的更多信息,请阅读Security-Enhanced Linux主页。该目标仅在mangle表中有效,并与SECMARK目标一起使用,其中SECMARK目标用于设置原始标记,然后CONNSECMARK用于在整个连接上设置标记。
The CONNSECMARK target sets a SELinux security context mark to or from a packet mark. For further information on SELinux, read more at the Security-Enhanced Linux homepage. The target is only valid in the mangle table and is used together with the SECMARK target, where the SECMARK target is used to set the original mark, and then the CONNSECMARK is used to set the mark on the whole connection.
SELinux 超出了本文档的范围,但基本上它是对 Linux 的强制访问控制的补充。这比大多数 Linux 和 Unix 安全控制的原始安全系统更加细粒度。每个对象都可以具有与其连接的安全属性或安全上下文,然后在允许或拒绝执行特定任务之前将这些属性相互匹配。该目标将允许在连接上设置安全上下文。
SELinux is beyond the scope of this document, but basically it is an addition of Mandatory Access Control to Linux. This is more finegrained than the original security systems of most Linux and Unix security controls. Each object can have security attributes, or security context, connected to it, and these attributes are then matched to eachother before allowing or denying a specific task to be performed. This target will allow a security context to be set on a connection.
表 11-4。CONNSECMARK 目标选项
Table 11-4. CONNSECMARK target options
| 选项 | - 节省 |
| 例子 | iptables -t mangle -A PREROUTING -p tcp --dport 80 -j CONNSECMARK --save |
| 解释 | 如果连接之前未标记,则将安全上下文标记从数据包保存到连接。 |
| 选项 | - 恢复 |
| 例子 | iptables -t mangle -A PREROUTING -p tcp --dport 80 -j CONNSECMARK --restore |
| 解释 | 如果数据包上没有设置安全上下文标记,--restore 选项将设置与数据包上的连接关联的安全上下文标记。 |
DNAT目标用于进行目标网络地址转换,这意味着它用于重写Destination IP数据包的地址。如果数据包匹配,并且这是规则的目标,则该数据包以及同一流中的所有后续数据包将被转换,然后路由到正确的设备、主机或网络。这个目标非常有用,例如,当您有一台主机在 LAN 内运行您的 Web 服务器
,但没有为其提供可在 Internet 上运行的真实 IP 时。然后,您可以告诉防火墙将所有前往其自己的 HTTP 端口的数据包转发到 LAN 内的真实 Web
服务器。我们还可以指定整个目标 IP 地址范围,DNAT 机制将为每个流随机选择目标 IP 地址。因此,我们将能够通过这样做来处理某种负载平衡。
The DNAT target is used to do Destination
Network Address Translation, which means that it is used to
rewrite the Destination IP address of a packet. If a packet is
matched, and this is the target of the rule, the packet, and all subsequent
packets in the same stream will be translated, and then routed on to the
correct device, host or network. This target can be extremely useful, for
example,when you have a host running your web server inside a
LAN, but no real IP to give it that will work on the
Internet. You could then tell the firewall to forward all packets going to its
own HTTP port, on to the real web server within the
LAN. We may also specify a whole range of destination IP
addresses, and the DNAT mechanism will choose the
destination IP address at random for each stream. Hence, we will be able to
deal with a kind of load balancing by doing this.
请注意,DNAT 目标仅在 nat 表中的 PREROUTING 和 OUTPUT 链以及从任何列出的链中调用的任何链中可用。请注意,包含 DNAT 目标的链不能从任何其他链(例如 POSTROUTING 链)中使用。
Note that the DNAT target is only available within the PREROUTING and OUTPUT chains in the nat table, and any of the chains called upon from any of those listed chains. Note that chains containing DNAT targets may not be used from any other chains, such as the POSTROUTING chain.
表 11-5。DNAT 目标选项
Table 11-5. DNAT target options
| 选项 | --到目的地 |
| 例子 | iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10 |
| 解释 | --to-destination 选项告诉 DNAT 机制在 IP 标头中设置哪个目标 IP,以及将匹配的数据包发送到何处。上面的示例会将所有发往 IP 地址 15.45.23.67 的数据包发送到LAN范围IP,即 192.168.1.1 到 10。请注意,如前所述,单个流将始终使用同一主机,并且每个流将随机分配一个 IP 地址,该地址始终是该流中的目的地。我们也可以只指定一个 IP 地址,在这种情况下,我们将始终连接到同一主机。另请注意,我们可能会添加流量将重定向到的端口或端口范围。例如,这是通过向我们要将数据包进行 DNAT 转换的 IP 地址添加 :80 语句来完成的。例如,规则可能类似于 --to-destination 192.168.1.1:80,或者如果我们想指定端口范围,则类似于 --to-destination 192.168.1.1:80-100。正如您所看到的,DNAT 目标的语法与 SNAT 目标几乎相同,尽管它们执行两种完全不同的操作。 |
由于 DNAT 需要做大量工作才能正常工作,因此我决定添加有关如何使用它的详细说明。让我们举一个简单的例子来说明正常情况下事情是如何完成的。我们希望通过互联网连接发布我们的网站。我们只有一个 IP 地址,HTTP 服务器位于我们的内部网络。我们的防火墙具有外部 IP 地址 $INET_IP,我们的 HTTP 服务器具有内部 IP 地址 $HTTP_IP,最后防火墙具有内部 IP 地址 $LAN_IP。首先要做的就是将以下简单规则添加到 nat 表中的 PREROUTING 链中:
Since DNAT requires quite a lot of work to work properly, I have decided to add a larger explanation on how to work with it. Let's take a brief example on how things would be done normally. We want to publish our website via our Internet connection. We only have one IP address, and the HTTP server is located on our internal network. Our firewall has the external IP address $INET_IP, and our HTTP server has the internal IP address $HTTP_IP and finally the firewall has the internal IP address $LAN_IP. The first thing to do is to add the following simple rule to the PREROUTING chain in the nat table:
iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \
--到目的地$HTTP_IP
iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \
--to-destination $HTTP_IP
现在,所有从 Internet 发送到防火墙端口 80 的数据包都将被重定向(或 DNAT)到我们的内部 HTTP 服务器。如果您从互联网上进行测试,一切都应该完美无缺。那么,如果您尝试从与 HTTP 服务器位于同一本地网络上的主机进行连接,会发生什么情况?它根本行不通。这确实是路由的问题。我们首先剖析正常情况下会发生什么。外部盒子有 IP 地址 $EXT_BOX,以保持可读性。
Now, all packets from the Internet going to port 80 on our firewall are redirected (or DNAT'ed) to our internal HTTP server. If you test this from the Internet, everything should work just perfect. So, what happens if you try connecting from a host on the same local network as the HTTP server? It will simply not work. This is a problem with routing really. We start out by dissecting what happens in a normal case. The external box has IP address $EXT_BOX, to maintain readability.
数据包离开连接主机,前往 $INET_IP 和源 $EXT_BOX。
Packet leaves the connecting host going to $INET_IP and source $EXT_BOX.
数据包到达防火墙。
Packet reaches the firewall.
防火墙 DNAT 是数据包,并通过所有不同的链等运行数据包。
Firewall DNAT's the packet and runs the packet through all different chains etcetera.
数据包离开防火墙并传输至 $HTTP_IP。
Packet leaves the firewall and travels to the $HTTP_IP.
数据包到达 HTTP 服务器,并且 HTTP 框通过防火墙进行回复(如果路由数据库已将其输入为 $EXT_BOX 的网关)。通常,这将是 HTTP 服务器的默认网关。
Packet reaches the HTTP server, and the HTTP box replies back through the firewall, if that is the box that the routing database has entered as the gateway for $EXT_BOX. Normally, this would be the default gateway of the HTTP server.
防火墙再次对数据包进行 Un-DNAT 处理,因此该数据包看起来就像是从防火墙本身回复的。
Firewall Un-DNAT's the packet again, so the packet looks as if it was replied to from the firewall itself.
回复数据包照常返回客户端 $EXT_BOX。
Reply packet travels as usual back to the client $EXT_BOX.
现在,我们将考虑如果数据包是由与 HTTP 服务器本身位于同一网络上的客户端生成的,会发生什么情况。客户端的 IP 地址为 $LAN_BOX,而其余计算机保持相同的设置。
Now, we will consider what happens if the packet was instead generated by a client on the same network as the HTTP server itself. The client has the IP address $LAN_BOX, while the rest of the machines maintain the same settings.
数据包离开 $LAN_BOX 到 $INET_IP。
Packet leaves $LAN_BOX to $INET_IP.
数据包到达防火墙。
The packet reaches the firewall.
数据包将进行 DNAT 处理,并执行所有其他所需的操作,但是数据包未进行 SNAT 处理,因此数据包上使用相同的源 IP 地址。
The packet gets DNAT'ed, and all other required actions are taken, however, the packet is not SNAT'ed, so the same source IP address is used on the packet.
数据包离开防火墙并到达 HTTP 服务器。
The packet leaves the firewall and reaches the HTTP server.
HTTP 服务器尝试响应该数据包,并在路由数据库中发现该数据包来自同一网络上的本地机器,因此尝试将数据包直接发送到原始源 IP 地址(现在成为目标 IP)地址)。
The HTTP server tries to respond to the packet, and sees in the routing databases that the packet came from a local box on the same network, and hence tries to send the packet directly to the original source IP address (which now becomes the destination IP address).
数据包到达客户端,客户端会感到困惑,因为返回数据包不是来自它向其发送原始请求的主机。因此,客户端丢弃回复数据包,并等待“真实”回复。
The packet reaches the client, and the client gets confused since the return packet does not come from the host that it sent the original request to. Hence, the client drops the reply packet, and waits for the "real" reply.
此问题的简单解决方案是对进入防火墙并离开我们知道要对其进行 DNAT 的主机或 IP 的所有数据包进行 SNAT。例如,考虑上面的规则。我们对进入防火墙、目的地为 $HTTP_IP 端口 80 的数据包进行 SNAT,以便它们看起来好像来自 $LAN_IP。这将强制 HTTP 服务器将数据包发送回我们的防火墙,防火墙对数据包进行 Un-DNAT 处理并将其发送到客户端。该规则看起来像这样:
The simple solution to this problem is to SNAT all packets entering the firewall and leaving for a host or IP that we know we do DNAT to. For example, consider the above rule. We SNAT the packets entering our firewall that are destined for $HTTP_IP port 80 so that they look as if they came from $LAN_IP. This will force the HTTP server to send the packets back to our firewall, which Un-DNAT's the packets and sends them on to the client. The rule would look something like this:
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \
--到源$LAN_IP
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \
--to-source $LAN_IP
请记住,POSTROUTING 链是在链中的最后处理的,因此数据包一旦到达该特定链就已经进行了 DNAT 处理。这就是我们根据内部地址来匹配数据包的原因。
Remember that the POSTROUTING chain is processed last of the chains, and hence the packet will already be DNAT'ed once it reaches that specific chain. This is the reason that we match the packets based on the internal address.
最后一条规则将严重损害您的日志记录,因此建议不要使用此方法,但整个示例仍然有效。将会发生的情况是,数据包来自 Internet,经过 SNAT 和 DNAT,最后到达 HTTP 服务器(例如)。HTTP 服务器现在只看到请求,就好像它来自防火墙一样,因此记录 来自 Internet 的所有请求,就好像它们来自防火墙一样。 This last rule will seriously harm your logging, so it is really advisable not to use this method, but the whole example is still a valid one. What will happen is this, packet comes from the Internet, gets SNAT'ed and DNAT'ed, and finally hits the HTTP server (for example). The HTTP server now only sees the request as if it was coming from the firewall, and hence logs all requests from the internet as if they came from the firewall. 这也可能产生更严重的影响。在 LAN 上设置一个 SMTP 服务器,它允许来自内部网络的请求,并且您将防火墙设置为将 SMTP 流量转发到该服务器。您现在已经有效地创建了一个开放中继 SMTP 服务器,其日志记录极其糟糕! This can also have even more severe implications. Take an SMTP server on the LAN, that allows requests from the internal network, and you have your firewall set up to forward SMTP traffic to it. You have now effectively created an open relay SMTP server, with horrenduously bad logging! 解决此问题的一种方法是简单地使 SNAT 规则在匹配部分更加具体,并且仅对来自 LAN 接口的数据包起作用。换句话说,也将 --src $LAN_IP_RANGE 添加到整个命令中。这将使规则仅适用于来自 LAN 的流,因此不会影响源 IP,因此日志看起来会正确,但来自 LAN 的流除外。 One solution to this problem is to simply make the SNAT rule even more specific in the match part, and to only work on packets that come in from our LAN interface. In other words, add a --src $LAN_IP_RANGE to the whole command as well. This will make the rule only work on streams that come in from the LAN, and hence will not affect the Source IP, so the logs will look correct, except for streams coming from our LAN. 换句话说,您最好通过为 LAN 设置单独的 DNS 服务器或实际设置单独的 DMZ 来解决这些问题,如果您有钱,最好选择后者。 You will, in other words, be better off solving these problems by either setting up a separate DNS server for your LAN, or to actually set up a separate DMZ, the latter being preferred if you have the money. |
您认为现在这应该足够了,而且确实如此,除非考虑整个场景的最后一个方面。如果防火墙本身尝试访问HTTP服务器,它会去哪里呢?现在看来,不幸的是,它会尝试访问自己的 HTTP 服务器,而不是驻留在 $HTTP_IP 上的服务器。为了解决这个问题,我们还需要在 OUTPUT 链中添加 DNAT 规则。按照上面的示例,这应该类似于以下内容:
You think this should be enough by now, and it really is, unless considering one final aspect to this whole scenario. What if the firewall itself tries to access the HTTP server, where will it go? As it looks now, it will unfortunately try to get to its own HTTP server, and not the server residing on $HTTP_IP. To get around this, we need to add a DNAT rule in the OUTPUT chain as well. Following the above example, this should look something like the following:
iptables -t nat -A 输出 --dst $INET_IP -p tcp --dport 80 -j DNAT \
--到目的地$HTTP_IP
iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \
--to-destination $HTTP_IP
添加这个最终规则应该可以让一切正常运行。所有与 HTTP 服务器不在同一网络上的独立网络都将顺利运行,与 HTTP 服务器位于同一网络上的所有主机都将能够连接,最后,防火墙也将能够进行正确的连接。现在一切正常,应该不会出现任何问题。
Adding this final rule should get everything up and running. All separate networks that do not sit on the same net as the HTTP server will run smoothly, all hosts on the same network as the HTTP server will be able to connect and finally, the firewall will be able to do proper connections as well. Now everything works and no problems should arise.
每个人都应该意识到这些规则只会影响数据包如何正确进行 DNAT 和 SNAT。除了这些规则之外,您可能还需要过滤表(FORWARD 链)中的额外规则以允许数据包也穿过这些链。不要忘记所有数据包都已经通过了 PREROUTING 链,因此它们的目标地址应该已经被 DNAT 重写。 Everyone should realize that these rules only affect how the packet is DNAT'ed and SNAT'ed properly. In addition to these rules, you may also need extra rules in the filter table (FORWARD chain) to allow the packets to traverse through those chains as well. Don't forget that all packets have already gone through the PREROUTING chain, and should hence have their destination addresses rewritten already by DNAT. |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
DROP 目标正如它所说的那样,它将丢弃死包并且不会执行任何进一步的处理。完全匹配规则但被丢弃的数据包将被阻止。请注意,此操作在某些情况下可能会产生不良影响,因为它可能会在任一主机上留下死套接字。在这种情况下,更好的解决方案是使用 REJECT 目标,特别是当您想要阻止端口扫描器获取太多信息(例如过滤端口等)时。另请注意,如果子链中对数据包采取了 DROP 操作,则该数据包将不会在当前或任何其他表中的任何主链中得到处理。换句话说,数据包完全死了。正如我们之前所看到的,目标不会向任一方向发送任何类型的信息,
The DROP target does just what it says, it drops packets dead and will not carry out any further processing. A packet that matches a rule perfectly and is then Dropped will be blocked. Note that this action might in certain cases have an unwanted effect, since it could leave dead sockets around on either host. A better solution in cases where this is likely would be to use the REJECT target, especially when you want to block port scanners from getting too much information, such as on filtered ports and so on. Also note that if a packet has the DROP action taken on it in a subchain, the packet will not be processed in any of the main chains either in the present or in any other table. The packet is in other words totally dead. As we've seen previously, the target will not send any kind of information in either direction, nor to intermediaries such as routers.
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
这是更改数据包内的 DSCP(区分服务字段)标记的目标。DSCP 目标能够在 TCP 数据包内设置任何 DSCP 值,这是告诉路由器相关数据包优先级的一种方式。有关 DSCP 的更多信息,请参阅IPv4 和 IPv6 标头 RFC 文档中的 RFC 2474 - 差分服务字段(DS 字段)的定义。
This is a target that changes the DSCP(Differentiated Services Field) marks inside a packet. The DSCP target is able to set any DSCP value inside a TCP packet, which is a way of telling routers the priority of the packet in question. For more information about DSCP, look at the RFC 2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers RFC document.
基本上,DSCP 是一种将不同服务区分为不同类别的方法,并在此基础上通过路由器赋予它们不同的优先级。通过这种方式,您可以为交互式 TCP 会话(例如 telnet、SSH、POP3)提供非常高的快速连接,但这可能不太适合大批量传输。另一方面,如果连接的重要性较低(SMTP,或任何您归类为低优先级的连接),您可以通过一个大型网络发送它,其延迟比其他网络更差,这比使用速度更快且更便宜的网络更便宜。较低的延迟连接。
Basically, DSCP is a way of differentiating different services into separate categories, and based on this, give them different priority through the routers. This way, you can give interactive TCP sessions (such as telnet, SSH, POP3) a very high fast connection, that may not be very suitable for large bulk transfers. If on the other hand the connection is one of low importance (SMTP, or whatever you classify as low priority), you could send it over a large bulky network with worse latency than the other network, that is cheaper to utilize than the faster and lower latency connections.
表 11-6。DSCP 目标选项
Table 11-6. DSCP target options
| 选项 | --设置 dscp |
| 例子 | iptables -t mangle -A FORWARD -p tcp --dport 80 -j DSCP --set-dscp 1 |
| 解释 | 这会将 DSCP 值设置为指定值。这些值可以通过类设置(见下文),也可以使用 --set-dscp 设置,后者采用整数值或十六进制值。 |
| 选项 | --set-dscp-class |
| 例子 | iptables -t mangle -A FORWARD -p tcp --dport 80 -j DSCP --set-dscp-class EF |
| 解释 | 这根据预定义的 DiffServ 类设置 DSCP 字段。一些可能的值包括 EF、BE 以及可用的 CSxx 和 AFxx 值。您可以在使用 DSCP 站点实施服务质量策略中找到更多信息。请注意,--set-dscp-class 和 --set-dscp 命令是互斥的,这意味着您不能在同一命令中使用它们! |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
如果以正确的方式使用,这个目标可以是伟大的。简单地说,ECN 目标可用于重置 IPv4 标头中的 ECN 位,或者正确地说,至少将它们重置为 0。由于 ECN 在网络上是一个相对较新的事物,因此存在一些问题。例如,它使用原始 RFC 中为 TCP 协议定义的 2 位为 0。某些路由器和其他互联网设备不会转发这些位设置为 1 的数据包。如果您想至少使用部分例如,您可以将 ECN 位重置为 0,以便您知道由于 ECN 而无法访问的特定网络。
This target can be great, used in the correct way. Simply put, the ECN target can be used to reset the ECN bits from the IPv4 header, or to put it correctly, reset them to 0 at least. Since ECN is a relatively new thing on the net, there are problems with it. For example, it uses 2 bits that are defined in the original RFC for the TCP protocol to be 0. Some routers and other internet appliances will not forward packets that have these bits set to 1. If you want to make use of at least parts of the ECN functionality from your hosts, you could for example reset the ECN bits to 0 for specific networks that you know you are having troubles reaching because of ECN.
请注意,无法在流中打开 ECN。根据 RFC 的规定,这是不允许的,而且无论如何也是不可能的。流的两个端点必须协商 ECN。如果我们打开它,那么其中一台主机不会意识到这一点,并且无法正确响应 ECN 通知。 Please do note that it isn't possible to turn ECN on in the middle of a stream. It isn't allowed according to the RFC's, and it isn't possible anyways. Both endpoints of the stream must negotiate ECN. If we turn it on, then one of the hosts is not aware of it, and can't respond properly to the ECN notifications. |
表 11-7。ECN 目标选项
Table 11-7. ECN target options
| 选项 | --ecn-tcp-删除 |
| 例子 | iptables -t mangle -A FORWARD -p tcp --dport 80 -j ECN --ecn-tcp-remove |
| 解释 | ECN 目标仅采用一个参数,即 --ecn-tcp-remove 参数。这告诉目标删除 TCP 标头内的 ECN 位。阅读上文了解更多信息。 |
在 Linux 内核 2.5 和 2.6 下运行。 Works under Linux kernel 2.5 and 2.6. |
LOG 目标是专门为记录有关数据包的详细信息而设计的。例如,这些可能被视为非法。或者,日志记录可以纯粹用于错误查找和错误查找。LOG 目标将返回数据包的特定信息,例如大多数 IP 标头和其他有趣的信息。它通过内核日志记录工具(通常是 syslogd)来完成此操作。然后可以使用 dmesg 或从 syslogd 日志或其他程序或应用程序直接读取此信息。这是用于调试规则集的绝佳目标,以便您可以查看哪些数据包去了哪里以及对哪些数据包应用了哪些规则。另请注意,当您在生产防火墙上测试您不能 100% 确定的规则时,使用 LOG 目标而不是 DROP 目标可能是一个非常好的主意,因为规则集中的语法错误可能会导致用户出现严重的连接问题。另请注意,如果您使用真正广泛的日志记录,ULOG 目标可能会很有趣,因为 ULOG 目标支持直接记录到 MySQL 数据库等。
The LOG target is specially designed for logging detailed information about packets. These could, for example, be considered as illegal. Or, logging can be used purely for bug hunting and error finding. The LOG target will return specific information on packets, such as most of the IP headers and other information considered interesting. It does this via the kernel logging facility, normally syslogd. This information may then be read directly with dmesg, or from the syslogd logs, or with other programs or applications. This is an excellent target to use to debug your rule-sets, so that you can see what packets go where and what rules are applied on what packets. Note as well that it could be a really great idea to use the LOG target instead of the DROP target while you are testing a rule you are not 100% sure about on a production firewall, since a syntax error in the rule-sets could otherwise cause severe connectivity problems for your users. Also note that the ULOG target may be interesting if you are using really extensive logging, since the ULOG target has support for direct logging to MySQL databases and suchlike.
请注意,如果您将不需要的日志直接记录到控制台,这不是 iptables 或 Netfilter 问题,而是由 syslogd 配置引起的问题 - 最有可能是/etc/syslog.conf。有关此类问题的信息,请阅读 man syslog.conf 中的更多内容。 Note that if you get undesired logging direct to consoles, this is not an iptables or Netfilter problem, but rather a problem caused by your syslogd configuration - most probably /etc/syslog.conf. Read more in man syslog.conf for information about this kind of problem. 您可能还需要调整 dmesg 设置。dmesg 是更改应在控制台上显示的内核错误的命令。dmesg -n 1 应防止所有消息显示在控制台上,紧急消息除外。dmesg 消息级别与 syslogd 级别完全匹配,并且它仅适用于来自内核设施的日志消息。有关详细信息,请参阅 man dmesg。 You may also need to tweak your dmesg settings. dmesg is the command that changes which errors from the kernel that should be shown on the console. dmesg -n 1 should prevent all messages from showing up on the console, except panic messages. The dmesg message levels matches exactly the syslogd levels, and it only works on log messages from the kernel facility. For more information, see man dmesg. |
LOG 目标当前采用五个选项,如果您有特定的信息需求,或者想要将不同的选项设置为特定值,则可能会对这些选项感兴趣。下面列出了它们。
The LOG target currently takes five options that could be of interest if you have specific information needs, or want to set different options to specific values. They are all listed below.
表 11-8。日志目标选项
Table 11-8. LOG target options
| 选项 | --日志级别 |
| 例子 | iptables -A FORWARD -p tcp -j LOG --日志级别调试 |
| 解释 | 该选项告诉 iptables 和 syslog 使用哪个日志级别。有关日志级别的完整列表,请阅读syslog.conf手册。通常有以下日志级别或通常提到的优先级:debug、info、notice、warning、warn、err、error、crit、alert、emerg 和 panic。关键字error与err相同,warn与warning相同,panic与emerg相同。请注意,所有这三个都已弃用,换句话说,不要使用错误、警告和恐慌。优先级定义了所记录消息的严重性。所有消息都通过内核设施记录。换句话说,在 syslog.conf 中设置 kern.=info /var/log/ iptables文件,然后让 iptables 中的所有日志消息使用日志级别信息,将使所有消息出现在/var/log/iptables文件中。请注意,这里可能还有来自使用信息优先级的内核其他部分的其他消息。有关日志记录的更多信息,我建议您阅读 syslog 和syslog.conf手册页以及其他 HOWTO 等。 |
| 选项 | --日志前缀 |
| 例子 | iptables -A INPUT -p tcp -j LOG --log-prefix“输入数据包” |
| 解释 | 此选项告诉 iptables 为所有日志消息添加特定前缀,然后可以轻松地与 grep 或其他工具结合使用,以跟踪特定问题和不同规则的输出。前缀的长度最多为 29 个字母,包括空格和其他特殊符号。 |
| 选项 | --log-tcp-序列 |
| 例子 | iptables -A 输入 -p tcp -j 日志 --log-tcp-序列 |
| 解释 | 此选项将记录 TCP 序列号以及日志消息。TCP 序列号是特殊的数字,用于标识每个数据包及其在 TCP 序列中的位置,以及如何重组流。请注意,如果未经授权的用户或其他人可以读取日志,则此选项会构成安全风险。任何包含 iptables 输出的日志也是如此。 |
| 选项 | --log-tcp-选项 |
| 例子 | iptables -A FORWARD -p tcp -j LOG --log-tcp-options |
| 解释 | --log-tcp-options 选项记录 TCP 数据包标头中的不同选项,在尝试调试可能出错或实际出错的地方时非常有用。该选项不采用任何变量字段或类似的内容,就像大多数 LOG 选项一样。 |
| 选项 | --log-ip-选项 |
| 例子 | iptables -A FORWARD -p tcp -j LOG --log-ip-options |
| 解释 | --log-ip-options 选项将记录大部分 IP 数据包标头选项。这与 --log-tcp-options 选项完全相同,但适用于 IP 选项。当尝试调试或跟踪特定的罪魁祸首以及调试时,这些日志消息可能很有价值 - 与之前的选项相同。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
MARK 目标用于设置与特定数据包关联的 Netfilter 标记值。该目标仅在 mangle 表中有效,在外面不起作用。MARK 值可以与 Linux 中的高级路由功能结合使用,通过不同的路由发送不同的数据包,并告诉它们使用不同的队列规则(qdisc)等。有关高级路由的更多信息,请查看 Linux 高级路由和交通控制指南。请注意,标记值不是在实际数据包内设置的,而是在内核内与数据包相关联的值。换句话说,您不能为数据包设置 MARK,然后期望该 MARK 仍然存在于另一台主机上。如果这是您想要的,那么使用 TOS 目标会更好,它会破坏 IP 标头中的 TOS 值。
The MARK target is used to set Netfilter mark values that are associated with specific packets. This target is only valid in the mangle table, and will not work outside there. The MARK values may be used in conjunction with the advanced routing capabilities in Linux to send different packets through different routes and to tell them to use different queue disciplines (qdisc), etc. For more information on advanced routing, check out the Linux Advanced Routing and Traffic Control HOW-TO. Note that the mark value is not set within the actual packet, but is a value that is associated within the kernel with the packet. In other words, you can not set a MARK for a packet and then expect the MARK still to be there on another host. If this is what you want, you will be better off with the TOS target which will mangle the TOS value in the IP header.
表 11-9。标记目标选项
Table 11-9. MARK target options
| 选项 | --设置标记 |
| 例子 | iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2 |
| 解释 | 设置标记需要 --set-mark 选项。--set-mark 匹配采用整数值。例如,我们可以在特定的数据包流上设置标记2,或者在来自特定主机的所有数据包上设置标记2,然后在该主机上进行高级路由,以减少或增加网络带宽等。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
MASQUERADE 目标的使用方式与 SNAT 目标基本相同,但它不需要任何 --to-source 选项。原因是 MASQUERADE 目标被设计为可与拨号连接或 DHCP 连接等配合使用,这些连接在连接到相关网络时会获取动态 IP 地址。这意味着您应该仅使用具有动态分配的 IP 连接的 MASQUERADE 目标,而我们始终不知道其实际地址。如果您有静态 IP 连接,则应使用 SNAT 目标。
The MASQUERADE target is used basically the same as the SNAT target, but it does not require any --to-source option. The reason for this is that the MASQUERADE target was made to work with, for example, dial-up connections, or DHCP connections, which gets dynamic IP addresses when connecting to the network in question. This means that you should only use the MASQUERADE target with dynamically assigned IP connections, which we don't know the actual address of at all times. If you have a static IP connection, you should instead use the SNAT target.
当你伪装一个连接时,这意味着我们设置了特定网络接口上使用的IP地址而不是--to-source选项,并且IP地址是自动从有关特定接口的信息中获取的。MASQUERADE 目标还具有在接口关闭时忘记连接的效果,例如,如果我们终止特定接口,则这非常好。如果我们使用 SNAT 目标,我们可能会留下大量旧的连接跟踪数据,这些数据将放置数天,吞噬有用的连接跟踪内存。一般来说,在处理每次启动时都可能分配不同 IP 的拨号线路时,这是正确的行为。如果我们被分配了不同的 IP,连接无论如何都会丢失,
When you masquerade a connection, it means that we set the IP address used on a specific network interface instead of the --to-source option, and the IP address is automatically grabbed from the information about the specific interface. The MASQUERADE target also has the effect that connections are forgotten when an interface goes down, which is extremely good if we, for example, kill a specific interface. If we would have used the SNAT target, we may have been left with a lot of old connection tracking data, which would be lying around for days, swallowing up useful connection tracking memory. This is, in general, the correct behavior when dealing with dial-up lines that are probably assigned a different IP every time they are brought up. In case we are assigned a different IP, the connection is lost anyways, and it is more or less idiotic to keep the entry around.
即使您确实有静态 IP,仍然可以使用 MASQUERADE 目标而不是 SNAT,但是,这并不有利,因为它会增加额外的开销,并且将来可能会出现不一致,这会阻碍您现有的脚本和渲染他们“无法使用”。
It is still possible to use the MASQUERADE target instead of SNAT even though you do have a static IP, however, it is not favorable since it will add extra overhead, and there may be inconsistencies in the future which will thwart your existing scripts and render them "unusable".
请注意,MASQUERADE 目标仅在 nat 表中的 POSTROUTING 链内有效,就像 SNAT 目标一样。MASQUERADE 目标采用下面指定的一个选项,该选项是可选的。
Note that the MASQUERADE target is only valid within the POSTROUTING chain in the nat table, just as the SNAT target. The MASQUERADE target takes one option specified below, which is optional.
表 11-10。MASQUERADE 目标选项
Table 11-10. MASQUERADE target options
| 选项 | --到端口 |
| 例子 | iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000 |
| 解释 | --to-ports 选项用于设置要在传出数据包上使用的一个或多个源端口。您可以指定单个端口(例如 --to-ports 1025),也可以指定端口范围(例如 --to-ports 1024-3000)。换句话说,下端口范围定界符和上端口范围定界符用连字符分隔。这会更改默认 SNAT 端口选择,如SNAT 目标部分中所述。仅当规则匹配部分通过 --protocol 匹配指定 TCP 或 UDP 协议时,--to-ports 选项才有效。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
请注意,MIRROR 是危险的,并且仅作为新 conntrack 和 NAT 代码的示例代码而开发。它可能会导致危险的事情发生,如果使用不当,可能会造成非常严重的 DDoS/DoS。Avoif 不惜一切代价使用它!由于它的安全隐患,它已从 2.5 和 2.6 内核中删除! Be warned, the MIRROR is dangerous and was only developed as an example code of the new conntrack and NAT code. It can cause dangerous things to happen, and very serious DDoS/DoS will be possible if used improperly. Avoif using it at all costs! It was removed from 2.5 and 2.6 kernels due to it's bad security implications! |
MIRROR 目标只是一个实验和演示目标,我们警告您不要使用它,因为它可能会导致非常糟糕的循环,从而导致严重的拒绝服务。MIRROR 目标用于反转 IP 标头中的源字段和目标字段,然后重新传输数据包。这可能会产生一些非常有趣的效果,而且我敢打赌,由于这个目标,现在不仅仅是一个红脸破解者破解了自己的盒子。至少可以说,使用这个目标的效果是显而易见的。假设我们在计算机 A 上为端口 80 设置了一个 MIRROR 目标。如果主机 B 来自 yahoo.com,并尝试访问主机 A 上的 HTTP 服务器,则 MIRROR 目标将返回 yahoo 主机自己的网页(因为这就是请求的来源)。
The MIRROR target is an experimental and demonstration target only, and you are warned against using it, since it may result in really bad loops hence, among other things, resulting in serious Denial of Service. The MIRROR target is used to invert the source and destination fields in the IP header, and then to retransmit the packet. This can cause some really funny effects, and I'll bet that, thanks to this target, not just one red faced cracker has cracked his own box by now. The effect of using this target is stark, to say the least. Let's say we set up a MIRROR target for port 80 at computer A. If host B were to come from yahoo.com, and try to access the HTTP server at host A, the MIRROR target would return the yahoo host's own web page (since this is where the request came from).
请注意,MIRROR 目标仅在 INPUT、FORWARD 和 PREROUTING 链以及从这些链调用的任何用户定义链中有效。另请注意,过滤器、nat 或 mangle 表中的任何正常链都看不到由 MIRROR 目标产生的传出数据包,这可能会引起循环和其他问题。这可能会使目标成为不可预见的麻烦的原因。例如,主机可能会向使用 TTL 为 255 的 MIRROR 命令的另一台主机发送欺骗性数据包,同时欺骗自己的数据包,使其看起来像是来自使用 MIRROR 命令的第三台主机。然后数据包将不断地来回反弹,以完成要完成的跳数。如果只有 1 跳,数据包将来回跳 240-255 次。对于饼干来说还不错,换句话说,发送 1500 字节的数据会占用 380 KB 的连接。请注意,对于破解者或脚本小子来说,这是最好的情况,无论我们如何称呼他们。
Note that the MIRROR target is only valid within the INPUT, FORWARD and PREROUTING chains, and any user-defined chains which are called from those chains. Also note that outgoing packets resulting from the MIRROR target are not seen by any of the normal chains in the filter, nat or mangle tables, which could give rise to loops and other problems. This could make the target the cause of unforeseen headaches. For example, a host might send a spoofed packet to another host that uses the MIRROR command with a TTL of 255, at the same time spoofing its own packet, so as to seem as if it comes from a third host that uses the MIRROR command. The packet will then bounce back and forth incessantly, for the number of hops there are to be completed. If there is only 1 hop, the packet will jump back and forth 240-255 times. Not bad for a cracker, in other words, to send 1500 bytes of data and eat up 380 kbyte of your connection. Note that this is a best case scenario for the cracker or script kiddie, whatever we want to call them.
在 Linux 内核 2.3 和 2.4 下工作。由于其固有的不安全性,它已从 2.5 和 2.6 内核中删除。不要使用这个目标! Works under Linux kernel 2.3 and 2.4. It was removed from 2.5 and 2.6 kernels due to it's inherent insecurity. Do not use this target! |
NETMAP 是 SNAT 和 DNAT 目标的新实现,其中 IP 地址的主机部分未更改。它为整个网络提供了1:1的NAT功能,这是标准SNAT和DNAT功能所不具备的。例如,假设我们有一个包含 254 个使用私有 IP 地址的主机的网络(/24 网络),并且我们刚刚获得了一个新的公共 IP 地址 /24 网络。我们可以简单地使用 NETMAP 目标,例如 -j NETMAP -to 10.5.6.0/24 ,瞧,所有主机都被视为 10.5.6,而不是四处走动并更改每台主机的 IP .x 当他们离开防火墙时。例如,192.168.0.26 将变为 10.5.6.26。
NETMAP is a new implementation of the SNAT and DNAT targets where the host part of the IP address isn't changed. It provides a 1:1 NAT function for whole networks which isn't available in the standard SNAT and DNAT functions. For example, lets say we have a network containing 254 hosts using private IP addresses (a /24 network), and we just got a new /24 network of public IP's. Instead of walking around and changing the IP of each and every one of the hosts, we would be able to simply use the NETMAP target like -j NETMAP -to 10.5.6.0/24 and voila, all the hosts are seen as 10.5.6.x when they leave the firewall. For example, 192.168.0.26 would become 10.5.6.26.
表 11-11。NETMAP 目标选项
Table 11-11. NETMAP target options
| 选项 | - 到 |
| 例子 | iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j NETMAP --to 10.5.6.0/24 |
| 解释 | 这是 NETMAP 目标的唯一选项。在上面的示例中,192.168.1.x 主机将直接转换为 10.5.6.x。 |
在 Linux 内核 2.5 和 2.6 下运行。 Works under Linux kernel 2.5 and 2.6. |
NFQUEUE 目标的使用方式与 QUEUE 目标非常相似,并且基本上是它的扩展。NFQUEUE 目标允许为单独的特定队列发送数据包。队列由 16 位 id 标识。
The NFQUEUE target is used much the same way as the QUEUE target, and is basically an extension of it. The NFQUEUE target allows for sending packets for separate and specific queues. The queue is identified by a 16-bit id.
该目标需要 nfnetlink_queue 内核支持才能运行。有关 NFQUEUE 目标可以执行的操作的更多信息,请参阅QUEUE 目标。
This target requires the nfnetlink_queue kernel support to run. For more information on what you can do with the NFQUEUE target, see the QUEUE target.
表 11-12。NFQUEUE 目标选项
Table 11-12. NFQUEUE target options
| 选项 | --队列号 |
| 例子 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30 |
| 解释 | --queue-num 选项指定要使用哪个队列并将队列中的数据发送到其中。如果跳过此选项,则使用默认队列 0。队列号是一个 16 位无符号整数,这意味着它可以采用 0 到 65535 之间的任何值。默认的 0 队列也由 QUEUE 目标使用。 |
适用于 Linux 内核 2.6.14 及更高版本。 Works under Linux kernel 2.6.14 and later. |
此目标用于关闭所有匹配此规则的数据包的连接跟踪。状态机章节的 未跟踪连接和原始表部分已详细讨论了目标。
This target is used to turn off connection tracking for all packets matching this rule. The target has been discussed at some length in the Untracked connections and the raw table section of the The state machine chapter.
该目标没有任何选项,并且非常易于使用。匹配您不希望跟踪的数据包,然后在与您不希望跟踪的数据包匹配的规则上设置 NOTRACK 目标。
The target takes no options and is very easy to use. Match the packets you wish to not track, and then set the NOTRACK target on the rules matching the packets you don't wish to track.
目标仅在原始表内有效。 The target is only valid inside the raw table. |
在最新的 Linux 2.6 内核下工作。 Works under late Linux 2.6 kernels. |
QUEUE 目标用于将数据包排队到用户态程序和应用程序。它与 iptables 无关的程序或实用程序结合使用,并且可以与网络记帐一起使用,或者用于代理或过滤数据包的特定和高级应用程序。我们不会深入讨论这个目标,因为此类应用程序的编码超出了本教程的范围。首先,这会花费太多时间,其次,此类文档与 Netfilter 和 iptables 的编程方面没有任何关系。所有这些都应该在Netfilter Hacking HOW-TO中得到很好的介绍。
The QUEUE target is used to queue packets to User-land programs and applications. It is used in conjunction with programs or utilities that are extraneous to iptables and may be used, for example, with network accounting, or for specific and advanced applications which proxy or filter packets. We will not discuss this target in depth, since the coding of such applications is out of the scope of this tutorial. First of all it would simply take too much time, and secondly such documentation does not have anything to do with the programming side of Netfilter and iptables. All of this should be fairly well covered in the Netfilter Hacking HOW-TO.
从内核 2.6.14 开始,netfilter 的行为发生了变化。一个用于与队列通信的新系统已经被设计出来,称为nfnetlink_queue。如今,QUEUE 目标基本上是指向 NFQUEUE 0 的指针。对于编程问题,还是看上面的链接。这需要 nfnetlink_queue.ko模块。 As of kernel 2.6.14 the behavior of netfilter has changed. A new system for talking to the QUEUE has been deviced, called the nfnetlink_queue. The QUEUE target is basically a pointer to the NFQUEUE 0 nowadays. For programming questions, still see the above link. This requires the nfnetlink_queue.ko module. |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
REDIRECT 目标用于将数据包和流重定向到机器本身。这意味着我们可以将所有发往 HTTP 端口的数据包重定向到我们自己主机上的 HTTP 代理(如鱿鱼)。本地生成的数据包被映射到 127.0.0.1 地址。换句话说,这会将转发的数据包或类似内容的目标地址重写为我们自己的主机。当我们需要透明代理(其中LAN主机根本不知道代理) 时,REDIRECT 目标非常有用。
The REDIRECT target is used to redirect packets and streams to the machine itself. This means that we could for example REDIRECT all packets destined for the HTTP ports to an HTTP proxy like squid, on our own host. Locally generated packets are mapped to the 127.0.0.1 address. In other words, this rewrites the destination address to our own host for packets that are forwarded, or something alike. The REDIRECT target is extremely good to use when we want, for example, transparent proxying, where the LAN hosts do not know about the proxy at all.
请注意,REDIRECT 目标仅在 nat 表的 PREROUTING 和 OUTPUT 链中有效。它在用户定义的链中也有效,这些链仅从这些链调用,而不是从其他地方调用。REDIRECT 目标仅采用一个选项,如下所述。
Note that the REDIRECT target is only valid within the PREROUTING and OUTPUT chains of the nat table. It is also valid within user-defined chains that are only called from those chains, and nowhere else. The REDIRECT target takes only one option, as described below.
表 11-13。重定向目标选项
Table 11-13. REDIRECT target options
| 选项 | --到端口 |
| 例子 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 |
| 解释 | --to-ports 选项指定要使用的目标端口或端口范围。如果没有 --to-ports 选项,则目标端口永远不会更改。如上所述,如果我们只想指定一个端口,则指定 --to-ports 8080。如果我们想要指定端口范围,我们可以像 --to-ports 8080-8090 那样执行,它告诉 REDIRECT 目标将数据包重定向到端口 8080 到 8090。请注意,此选项仅在指定的规则中可用带有 --protocol 匹配器的 TCP 或 UDP 协议,因为它在其他地方没有任何意义。 The --to-ports option specifies the destination port, or port range, to use. Without the --to-ports option, the destination port is never altered. This is specified, as above, --to-ports 8080 in case we only want to specify one port. If we would want to specify a port range, we would do it like --to-ports 8080-8090, which tells the REDIRECT target to redirect the packets to the ports 8080 through 8090. Note that this option is only available in rules specifying the TCP or UDP protocol with the --protocol matcher, since it wouldn't make any sense anywhere else. |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
REJECT 目标的工作原理与 DROP 目标基本相同,但它也会向发送被阻止数据包的主机发回一条错误消息。截至目前,REJECT 目标仅在 INPUT、FORWARD 和 OUTPUT 链或其子链中有效。毕竟,只有这些链才是放置此目标有意义的链。请注意,所有使用 REJECT 目标的链只能由 INPUT、FORWARD 和 OUTPUT 链调用,否则它们将不起作用。目前只有一个选项可以控制该目标的工作原理,尽管这可能需要大量的变量。如果您有 TCP/IP 的基本知识,其中大多数都相当容易理解。
The REJECT target works basically the same as the DROP target, but it also sends back an error message to the host sending the packet that was blocked. The REJECT target is as of today only valid in the INPUT, FORWARD and OUTPUT chains or their sub chains. After all, these would be the only chains in which it would make any sense to put this target. Note that all chains that use the REJECT target may only be called by the INPUT, FORWARD, and OUTPUT chains, else they won't work. There is currently only one option which controls the nature of how this target works, though this may in turn take a huge set of variables. Most of them are fairly easy to understand, if you have a basic knowledge of TCP/IP.
表 11-14。拒绝目标选项
Table 11-14. REJECT target options
| 选项 | --拒绝-with |
| 例子 | iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset |
| 解释 | 此选项告诉 REJECT 目标向发送我们拒绝的数据包的主机发送什么响应。一旦我们收到与指定此目标的规则相匹配的数据包,我们的主机将首先发送相关的回复,然后该数据包将被丢弃,就像 DROP 目标丢弃它一样。以下拒绝类型当前有效:icmp-net-unreachable、icmp-host-unreachable、icmp-port-unreachable、icmp-proto-unreachable、icmp-net-prohibited 和 icmp-host-prohibited。默认错误消息是向主机发送端口不可达。以上都是ICMP错误消息,可以根据自己的需要进行设置。您可以在附录ICMP 类型中找到有关其各种用途的更多信息。最后,还有一个名为 tcp-reset 的选项,它只能与 TCP 协议一起使用。tcp-reset 选项将告诉 REJECT 发送 TCP RST 数据包以回复发送主机。TCP RST 数据包用于正常关闭打开的 TCP 连接。有关 TCP RST 的更多信息,请阅读RFC 793 - 传输控制协议。正如 iptables 手册页中所述,这主要用于阻止身份探测,这种探测在将邮件发送到损坏的邮件主机时经常发生,否则这些主机不会接受您的邮件。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
RETURN 目标将导致当前数据包停止通过符合规则的链。如果它是另一条链的子链,则数据包将继续穿过上级链,就像什么都没发生一样。如果该链是主链,例如INPUT链,则数据包将采用默认策略。默认策略通常设置为 ACCEPT、DROP 或类似的。
The RETURN target will cause the current packet to stop traveling through the chain where it hit the rule. If it is the subchain of another chain, the packet will continue to travel through the superior chains as if nothing had happened. If the chain is the main chain, for example the INPUT chain, the packet will have the default policy taken on it. The default policy is normally set to ACCEPT, DROP or similar.
例如,假设一个数据包进入 INPUT 链,然后命中它匹配的规则,并告诉它 --jump Examples_CHAIN。然后,数据包将开始遍历 EXAMPLE_CHAIN,突然间它与设置了 --jump RETURN 目标的特定规则相匹配。然后它会跳回到INPUT链。另一个例子是数据包是否命中 INPUT 链中的 --jump RETURN 规则。然后,它将被删除到之前描述的默认策略,并且在此链中不会采取更多操作。
For example, let's say a packet enters the INPUT chain and then hits a rule that it matches and that tells it to --jump EXAMPLE_CHAIN. The packet will then start traversing the EXAMPLE_CHAIN, and all of a sudden it matches a specific rule which has the --jump RETURN target set. It will then jump back to the INPUT chain. Another example would be if the packet hit a --jump RETURN rule in the INPUT chain. It would then be dropped to the default policy as previously described, and no more actions would be taken in this chain.
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
SAME 目标的工作方式几乎与 SNAT 目标相同,但仍然有所不同。基本上,SAME 目标将尝试始终对网络上单个主机发起的所有连接使用相同的传出 IP 地址。例如,假设您有 1 个 /24 网络 (192.168.1.0) 和 3 个 IP 地址 (10.5.6.7-9)。现在,如果 192.168.1.20 第一次通过 .7 地址出去,防火墙将尝试保持该计算机始终通过该 IP 地址出去。
The SAME target works almost in the same fashion as the SNAT target, but it still differs. Basically, the SAME target will try to always use the same outgoing IP address for all connections initiated by a single host on your network. For example, say you have one /24 network (192.168.1.0) and 3 IP addresses (10.5.6.7-9). Now, if 192.168.1.20 went out through the .7 address the first time, the firewall will try to keep that machine always going out through that IP address.
表 11-15。相同的目标选项
Table 11-15. SAME target options
| 选项 | - 到 |
| 例子 | iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j SAME --to 10.5.6.7-10.5.6.9 |
| 解释 | 如您所见,--to 参数采用 - 符号将 2 个 IP 地址绑定在一起。这些 IP 地址以及其间的所有 IP 地址都是我们使用 SAME 算法 NAT 到的 IP 地址。 |
| 选项 | --诺德斯特 |
| 例子 | iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j SAME --to 10.5.6.7-10.5.6.9 --nodst |
| 解释 | 在正常操作下,SAME 目标会根据目标 IP 地址和源 IP 地址计算后续连接。使用 --nodst 选项,它仅使用源 IP 地址来查找 NAT 功能应将哪个传出 IP 用于特定连接。如果没有此参数,它将使用目标 IP 地址和源 IP 地址的组合。 |
在 Linux 内核 2.5 和 2.6 下运行。 Works under Linux kernel 2.5 and 2.6. |
SECMARK 目标用于在单个数据包上设置安全上下文标记,如 SELinux 和安全系统所定义。这在 Linux 中仍处于起步阶段,但将来应该会越来越多。由于 SELinux 超出了本文档的范围,因此我建议访问Security-Enhanced Linux 网页以获取更多信息。
The SECMARK target is used to set a security context mark on a single packet, as defined by SELinux and security systems. This is still somewhat in it's infancy in Linux, but should pick up more and more in the future. Since SELinux is out of the scope of this document, I suggest going to the Security-Enhanced Linux webpage for more information.
简而言之,SELinux 是一种新的、改进的安全系统,用于向 Linux 添加强制访问控制 (MAC),由 NSA 作为概念验证而实施。SELinux 基本上为不同的对象设置安全属性,然后将它们匹配到安全上下文中。SECMARK 目标用于在数据包上设置安全上下文,然后可以在安全子系统中使用该安全上下文进行匹配。
In brief, SELinux is a new and improved security system to add Mandatory Access Control (MAC) to Linux, implemented by NSA as a proof of concept. SELinux basically sets security attributes for different objects and then matches them into security contexts. The SECMARK target is used to set a security context on a packet which can then be used within the security subsystems to match on.
SECMARK 目标仅在 mangle 表中有效。 The SECMARK target is only valid in the mangle table. |
SNAT目标用于进行源网络地址转换,这意味着该目标将重写数据包的IP标头中的源IP地址。例如,当多台主机必须共享 Internet 连接时,这就是我们想要的。然后,我们可以在内核中打开 ip 转发,并编写一条 SNAT 规则,该规则会将所有从本地网络发出的数据包转换为我们自己的 Internet 连接的源 IP。如果不这样做,外界将不知道将回复数据包发送到哪里,因为我们的本地网络主要使用分配给 LAN 网络的 IANA 指定 IP 地址。如果我们按原样转发这些数据包,互联网上没有人会知道它们实际上来自我们。SNAT 目标完成此类工作所需的所有转换,
The SNAT target is used to do Source Network Address Translation, which means that this target will rewrite the Source IP address in the IP header of the packet. This is what we want, for example, when several hosts have to share an Internet connection. We can then turn on ip forwarding in the kernel, and write an SNAT rule which will translate all packets going out from our local network to the source IP of our own Internet connection. Without doing this, the outside world would not know where to send reply packets, since our local networks mostly use the IANA specified IP addresses which are allocated for LAN networks. If we forwarded these packets as is, no one on the Internet would know that they were actually from us. The SNAT target does all the translation needed to do this kind of work, letting all packets leaving our LAN look as if they came from a single host, which would be our firewall.
SNAT 目标仅在 POSTROUTING 链内的 nat 表内有效。换句话说,这是您可以使用 SNAT 的唯一链。只有连接中的第一个数据包会被 SNAT 破坏,之后使用同一连接的所有未来数据包也将被 SNAT 处理。此外,POSTROUTING 链中的初始规则将应用于同一流中的所有数据包。
The SNAT target is only valid within the nat table, within the POSTROUTING chain. This is in other words the only chain in which you may use SNAT. Only the first packet in a connection is mangled by SNAT, and after that all future packets using the same connection will also be SNATted. Furthermore, the initial rules in the POSTROUTING chain will be applied to all the packets in the same stream.
表 11-17。SNAT 目标选项
Table 11-17. SNAT target options
| 选项 | - 源 |
| 例子 | iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000 |
| 解释 | --to-source 选项用于指定数据包应使用哪个源。最简单的是,此选项采用一个 IP 地址,我们希望将其用作 IP 标头中的源 IP 地址。如果我们想在多个 IP 地址之间进行平衡,我们可以使用一系列 IP 地址,并用连字符分隔。例如,--to--source IP 号码可能类似于上面的示例:194.236.50.155-194.236.50.160。然后,我们打开的每个流的源 IP 将从这些中随机分配,并且单个流将始终对该流中的所有数据包使用相同的 IP 地址。我们还可以指定 SNAT 使用的端口范围。所有源端口将被限制为指定的端口。规则的端口位将如上例所示:1024-32000。仅当在相关规则的匹配中的某处指定了 -p tcp 或 -p udp 时,这才有效。如果可能的话,iptables 将始终尝试避免进行任何端口更改,但如果两台主机尝试使用相同的端口,iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。如果可能的话,iptables 将始终尝试避免进行任何端口更改,但如果两台主机尝试使用相同的端口,iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。如果可能的话,iptables 将始终尝试避免进行任何端口更改,但如果两台主机尝试使用相同的端口,iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。所有其他端口将映射到 1024 或更高版本。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。所有其他端口将映射到 1024 或更高版本。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
TCPMSS 目标可用于更改防火墙看到的 TCP SYN 数据包的 MSS(最大分段大小)值。MSS 值用于控制特定连接的数据包的最大大小。正常情况下,这意味着MTU(最大传输单元)值的大小减去40字节。这用于克服一些 ISP 和服务器阻止 ICMP 分段所需的数据包,这可能会导致非常奇怪的问题,主要可以描述为您的防火墙/路由器一切正常,但防火墙后面的本地主机无法交换大数据包。这可能意味着邮件服务器能够发送小邮件,但不能发送大邮件,Web 浏览器可以连接,但随后挂起,但没有收到任何数据,ssh 连接正常,但 scp 在初次握手后挂起。
The TCPMSS target can be used to alter the MSS (Maximum Segment Size) value of TCP SYN packets that the firewall sees. The MSS value is used to control the maximum size of packets for specific connections. Under normal circumstances, this means the size of the MTU (Maximum Transfer Unit) value, minus 40 bytes. This is used to overcome some ISP's and servers that block ICMP fragmentation needed packets, which can result in really weird problems which can mainly be described such that everything works perfectly from your firewall/router, but your local hosts behind the firewall can't exchange large packets. This could mean such things as mail servers being able to send small mails, but not large ones, web browsers that connect but then hang with no data received, and ssh connecting properly, but scp hangs after the initial handshake. In other words, everything that uses any large packets will be unable to work.
TCPMSS 目标能够通过更改通过连接发出的数据包的大小来解决这些问题。请注意,我们只需要在 SYN 数据包上设置 MSS,因为此后主机会处理 MSS。目标有两个参数。
The TCPMSS target is able to solve these problems, by changing the size of the packets going out through a connection. Please note that we only need to set the MSS on the SYN packet since the hosts take care of the MSS after that. The target takes two arguments.
表 11-18。TCPMSS 目标选项
Table 11-18. TCPMSS target options
| 选项 | --设置-mss |
| 例子 | iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o eth0 -j TCPMSS --set-mss 1460 |
| 解释 | --set-mss 参数显式设置所有传出数据包的特定 MSS 值。在上面的示例中,我们将通过 eth0 接口发出的所有 SYN 数据包的 MSS 设置为 1460 字节 - 以太网的正常 MTU 为 1500 字节,减去 40 字节为 1460 字节。只需要在 SYN 数据包中正确设置 MSS,然后对等主机就会自动处理 MSS。 |
| 选项 | --clamp-mss-to-pmtu |
| 例子 | iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o eth0 -j TCPMSS --clamp-mss-to-pmtu |
| 解释 | --clamp-mss-to-pmtu 会自动将 MSS 设置为正确的值,因此您无需显式设置它。它自动设置为 PMTU(路径最大传输单元)减去 40 字节,这对于大多数应用程序来说应该是一个合理的值。 |
在 Linux 内核 2.5 和 2.6 下运行。 Works under Linux kernel 2.5 and 2.6. |
TOS 目标用于设置 IP 标头中的服务类型字段。TOS 字段由 8 位组成,用于帮助路由数据包。这是可以在 iproute2 及其子系统中直接用于路由策略的字段之一。值得注意的是,如果您处理多个单独的防火墙和路由器,这是在这些路由器和防火墙之间的实际数据包内传播路由信息的唯一方法。如前所述,MARK 目标(设置与特定数据包关联的 MARK)仅在内核中可用,并且不能随数据包传播。如果您觉得需要传播特定数据包或流的路由信息,则应设置为此开发的 TOS 字段。
The TOS target is used to set the Type of Service field within the IP header. The TOS field consists of 8 bits which are used to help in routing packets. This is one of the fields that can be used directly within iproute2 and its subsystem for routing policies. Worth noting, is that if you handle several separate firewalls and routers, this is the only way to propagate routing information within the actual packet between these routers and firewalls. As previously noted, the MARK target - which sets a MARK associated with a specific packet - is only available within the kernel, and can't be propagated with the packet. If you feel a need to propagate routing information for a specific packet or stream, you should therefore set the TOS field, which was developed for this.
目前互联网上有很多路由器在这方面做得很糟糕,因此到目前为止,在将数据包发送到互联网之前尝试 TOS 修改可能有点无用。最好的情况是路由器不会关注 TOS 字段。最坏的情况是,他们会查看 TOS 字段并做错误的事情。然而,如上所述,如果您有一个包含多个路由器的大型 WAN 或 LAN,那么 TOS 字段绝对可以得到很好的利用。事实上,您可以根据数据包的 TOS 值,为数据包提供不同的路由和首选项 - 即使这可能仅限于您自己的网络。
There are currently a lot of routers on the Internet which do a pretty bad job at this, so as of now it may prove to be a bit useless to attempt TOS mangling before sending the packets on to the Internet. At best the routers will not pay any attention to the TOS field. At worst, they will look at the TOS field and do the wrong thing. However, as stated above, the TOS field can most definitely be put to good use if you have a large WAN or LAN with multiple routers. You then in fact have the possibility of giving packets different routes and preferences, based on their TOS value - even though this might be confined to your own network.
TOS 目标只能设置特定值或数据包上的命名值。这些预定义的 TOS 值可以在内核包含文件中找到,或更准确地说,在 Linux/ip.h文件中。原因有很多,而且您实际上不需要设置任何其他值;然而,有一些方法可以解决这个限制。为了解决只能设置数据包命名值的限制,您可以使用Matthew G. Marsh 维护的Paksecured Linux Kernel 补丁站点上提供的 FTOS 补丁。但是,请谨慎使用此补丁!除极端情况外,您不需要使用默认值以外的任何值。 The TOS target is only capable of setting specific values, or named values on packets. These predefined TOS values can be found in the kernel include files, or more precisely, the Linux/ip.h file. The reasons are many, and you should actually never need to set any other values; however, there are ways around this limitation. To get around the limitation of only being able to set the named values on packets, you can use the FTOS patch available at the Paksecured Linux Kernel patches site maintained by Matthew G. Marsh. However, be cautious with this patch! You should not need to use any other than the default values, except in extreme cases. |
请注意,此目标仅在 mangle 表内有效,不能在其外部使用。 Note that this target is only valid within the mangle table and can't be used outside it. |
另请注意,某些旧版本(1.2.2 或更低版本)的 iptables 提供了此目标的损坏实现,它没有修复损坏时的数据包校验和,因此导致数据包损坏并需要重新传输。这反过来很可能会导致进一步的损坏并且连接永远无法工作。 Also note that some old versions (1.2.2 or below) of iptables provided a broken implementation of this target which did not fix the packet checksum upon mangling, hence rendering the packets bad and in need of retransmission. That in turn would most probably lead to further mangling and the connection never working. |
TOS 目标仅采用一种选项,如下所述。
The TOS target only takes one option as described below.
表 11-19。TOS 目标选项
Table 11-19. TOS target options
| 选项 | --设置为 |
| 例子 | iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10 |
| 解释 | --set-tos 选项告诉 TOS mangler 在匹配的数据包上设置什么 TOS 值。该选项采用十六进制或十进制数值。由于 TOS 值由 8 位组成,因此该值可以是 0-255,或十六进制 0x00-0xFF。请注意,在标准 TOS 目标中,您只能使用可用的命名值(应该或多或少标准化),如前面的警告中所述。这些值为最小化延迟(十进制值 16,十六进制值 0x10)、最大化吞吐量(十进制值 8、十六进制值 0x08)、最大化可靠性(十进制值 4、十六进制值 0x04)、最小化成本(十进制值 2、十六进制 0x02) 或正常服务(十进制值 0,十六进制值 0x00)。大多数数据包的默认值为 Normal-Service,或 0。请注意,当然,您可以 使用实际名称而不是实际十六进制值来设置 TOS 值;事实上,通常建议这样做,因为与名称相关的值将来可能会更改。要获得“描述性值”的完整列表,请执行 iptables -j TOS -h。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
TTL 目标用于修改 IP 标头中的生存时间字段。一种有用的应用是将所有传出数据包上的所有生存时间值更改为相同的值。这样做的原因之一是,如果您的 ISP不允许您将多于一台计算机连接到同一 Internet 连接,并且该 ISP 会积极追求这一点。将所有 TTL 值设置为相同的值,实际上会让他们更难注意到您正在这样做。然后,我们可以将所有传出数据包的 TTL 值重置为标准化值,例如 Linux 内核中指定的 64。
The TTL target is used to modify the Time To Live field in the IP header. One useful application of this is to change all Time To Live values to the same value on all outgoing packets. One reason for doing this is if you have a bully ISP which don't allow you to have more than one machine connected to the same Internet connection, and who actively pursues this. Setting all TTL values to the same value, will effectively make it a little bit harder for them to notice that you are doing this. We may then reset the TTL value for all outgoing packets to a standardized value, such as 64 as specified in the Linux kernel.
有关如何设置 Linux 中使用的默认值的更多信息,请阅读 ip-sysctl.txt ,您可以在其他资源和链接附录中找到该文件。
For more information on how to set the default value used in Linux, read the ip-sysctl.txt, which you may find within the Other resources and links appendix.
TTL 目标仅在 mangle 表内有效,在其他地方无效。截至撰写本文时,有 3 个选项,所有选项均在下表中进行了描述。
The TTL target is only valid within the mangle table, and nowhere else. It takes 3 options as of writing this, all of them described below in the table.
表 11-20。TTL 目标选项
Table 11-20. TTL target options
| 选项 | --ttl-设置 |
| 例子 | iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64 |
| 解释 | --ttl-set 选项告诉 TTL 目标要在相关数据包上设置哪个 TTL 值。一个好的值应该是 64 左右。它不太长,也不太短。不要将此值设置得太高,因为它可能会影响您的网络,并且将此值设置得太高有点不道德,因为数据包可能会开始在两个配置错误的路由器之间来回反弹,并且 TTL 越高,在这种情况下,将会不必要地消耗更多的带宽。这个目标可以用来限制我们的客户的距离。DNS 服务器就是一个很好的例子,我们不希望客户端距离太远。 |
| 选项 | --ttl-dec |
| 例子 | iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1 |
| 解释 | --ttl-dec 选项告诉 TTL 目标将生存时间值减少 --ttl-dec 选项后指定的量。换句话说,如果传入数据包的 TTL 为 53 并且我们设置了 --ttl-dec 3,则该数据包将以 TTL 值 49 离开我们的主机。这样做的原因是网络代码会自动递减 TTL 值。 TTL 值减 1,因此数据包将减少 4 个步长,从 53 到 49。例如,当我们想要限制使用我们服务的人的距离时,可以使用此方法。例如,用户应该始终使用附近的 DNS,因此我们可以匹配离开 DNS 服务器的所有数据包,然后将其减少几个步骤。当然,对于这种用法,--set-ttl 可能是更好的主意。 |
| 选项 | --ttl-inc |
| 例子 | iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1 |
| 解释 | --ttl-inc 选项告诉 TTL 目标将生存时间值增加到 --ttl-inc 选项指定的值。这意味着我们应该使用 --ttl-inc 选项中指定的值来提高 TTL 值,如果我们指定 --ttl-inc 4,则以 TTL 53 进入的数据包将以 TTL 56 离开主机。同样的事情也发生在这里,就像前面的 --ttl-dec 选项示例一样,网络代码将自动将 TTL 值减 1,它总是这样做。这可以用来使我们的防火墙在跟踪路由等方面更加隐蔽。通过将所有传入数据包的 TTL 值设置得较高,我们可以有效地使防火墙对跟踪路由隐藏。追踪路线是让人又爱又恨的事情,因为它们提供了有关连接问题及其发生位置的出色信息,但同时,如果黑客/破解者以您为目标,它也会为您提供一些有关您的上游的有用信息。有关如何使用此功能的好示例,请参阅Ttl-inc.txt脚本。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
ULOG 目标用于提供匹配数据包的用户空间日志记录。如果数据包匹配并且设置了 ULOG 目标,则通过 netlink 套接字将数据包信息与整个数据包一起多播。然后,一个或多个用户空间进程可以订阅各种多播组并接收该数据包。换句话说,这是一个更完整、更复杂的日志记录工具,到目前为止仅由 iptables 和 Netfilter 使用,并且它包含更好的记录数据包的工具。该目标使我们能够将信息记录到 MySQL 数据库和其他数据库,从而使搜索特定数据包和对日志条目进行分组变得更加简单。您可以在ULOGD 项目页面找到 ULOGD 用户态应用程序。
The ULOG target is used to provide user-space logging of matching packets. If a packet is matched and the ULOG target is set, the packet information is multicasted together with the whole packet through a netlink socket. One or more user-space processes may then subscribe to various multicast groups and receive the packet. This is in other words a more complete and more sophisticated logging facility that is only used by iptables and Netfilter so far, and it contains much better facilities for logging packets. This target enables us to log information to MySQL databases, and other databases, making it much simpler to search for specific packets, and to group log entries. You can find the ULOGD user-land applications at the ULOGD project page.
表 11-21。ULOG 目标选项
Table 11-21. ULOG target options
| 选项 | --ulog-nlgroup |
| 例子 | iptables -A 输入 -p TCP --dport 22 -j ULOG --ulog-nlgroup 2 |
| 解释 | --ulog-nlgroup 选项告诉 ULOG 目标将数据包发送到哪个 netlink 组。netlink组有32个,简单指定为1-32。如果我们想到达 netlink 组 5,我们只需编写 --ulog-nlgroup 5。使用的默认 netlink 组是 1。 |
| 选项 | --ulog-前缀 |
| 例子 | iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-prefix “SSH 连接尝试:” |
| 解释 | --ulog-prefix 选项的工作方式与标准 LOG 目标的前缀值相同。此选项为所有日志条目添加用户指定的日志前缀。它可以是 32 个字符长,对于区分不同的日志消息及其来源绝对最有用。 |
| 选项 | --ulog-cprange |
| 例子 | iptables -A 输入 -p TCP --dport 22 -j ULOG --ulog-cprange 100 |
| 解释 | --ulog-cprange 选项告诉 ULOG 目标将数据包的多少字节发送到 ULOG 的用户空间守护进程。如果我们如上所述指定 100,我们会将整个数据包的 100 个字节复制到用户空间,其中希望包括整个标头,以及实际数据包中的一些前导数据。如果我们指定 0,则无论数据包大小如何,整个数据包都将被复制到用户空间。默认值为 0,因此整个数据包将被复制到用户空间。 |
| 选项 | --ulog-qthreshold |
| 例子 | iptables -A 输入 -p TCP --dport 22 -j ULOG --ulog-qthreshold 10 |
| 解释 | --ulog-qthreshold 选项告诉 ULOG 目标在实际将数据发送到用户空间之前有多少数据包在内核中排队。例如,如果我们将阈值设置为上面的 10,内核将首先在内核内部累积 10 个数据包,然后将其作为单个 netlink 多部分消息传输到外部用户空间。这里的默认值是1,因为向后兼容,用户空间守护进程以前不知道如何处理多部分消息。 |
可在 Linux 内核 2.3、2.4、2.5 和 2.6 下运行。 Works under Linux kernel 2.3, 2.4, 2.5 and 2.6. |
本章详细讨论了 Linux 中可用的每个目标。随着人们为 iptables 和 netfilter 编写越来越多的目标扩展,这个列表仍在增长,并且如您所见,它已经相当广泛。本章还讨论了每个目标可用的不同目标选项。
This chapter has discussed in detail each and every target that is available in Linux. This list is still growing as people write more and more target extensions for iptables and netfilter, and it is already quite extensive as you have seen. The chapter has also discussed the different target options available for each target.
下一章将深入探讨防火墙脚本的调试以及可用于执行此操作的技术。它将向您展示适度的调试技术(例如使用 bash 和 echo)以及一些更高级的工具(例如 nmap 和 nessus)。
The next chapter will delve into debugging your firewall scripts and what techniques are available for doing this. It will both show you moderate debugging techniques such as using bash and echo, to some more advanced tools such as nmap and nessus.
编写自己的规则集的一个重要且容易被忽视的方面是如何自行调试规则集,以及如何找到规则集中哪里出错了。本章将向您展示一些调试脚本并找出其中问题的基本步骤,以及一些需要查找的更详细的内容以及可以采取哪些措施来避免无法连接到防火墙如果您不小心在其上运行了错误的规则集。
One large and rather overlooked sides of writing your own rulesets is how to debug the rulesets on your own, and how to find where you have done your mistakes in the rulesets. This chapter will show you a few basic steps you can take to debug your scripts and find out what is wrong with them, as well as some more elaborate things to look for and what can be done to avoid being unable to connect to your firewall in case you accidentally run a bad ruleset on it.
这里教授的大部分内容都是基于规则集是用 bash shell 脚本编写的假设,但它们也应该很容易应用于其他环境。不幸的是,使用 iptables-save 保存的规则集是另一段代码,而且几乎所有这些调试方法都不会给您带来太多运气。另一方面,iptables-save 文件要简单得多,并且由于它们也不能包含任何创建特定规则的脚本代码,因此它们也更容易调试。
Most of what is taught here is based upon the assumption that the ruleset was written in bash shell scripts, but they should be easy to apply in other environments as well. Rulesets that have been saved with iptables-save are another piece of code alltogether unfortunately, and pretty much none of these debugging methods will give you much luck. On the other hand, iptables-save files are much simpler and since they can't contain any scripting code that will create specific rules either, they are much simpler to debug as well.
对于 iptables 和 netfilter 以及大多数防火墙来说,调试或多或少是必要的。99% 的防火墙的问题在于,最终由人来决定策略以及如何创建规则集,我可以向您保证,在编写规则集时很容易犯错误。有时,这些错误很难用肉眼看到,也很难看到它们穿过防火墙造成的漏洞。您不知道或不希望在脚本中出现的漏洞可能会对您的网络造成严重破坏,并为攻击者创造一个轻松的入口。使用一些好的工具就可以轻松找到大多数这些漏洞。
Debugging is more or less a necessity when it comes to iptables and netfilter and most firewalls in general. The problem with 99% of all firewalls is that in the end there is a human being that decides upon the policies and how the rulesets are created, and I can promise you, it is easy to make a mistake while writing your rulesets. Sometimes, these errors are very hard to see with the naked eye, or to see the holes that they are creating through the firewall. Holes that you don't know of or didn't intend to happen in your scripts can create havoc on your networks, and create an easy entry for your attackers. Most of these holes can be found rather easily with a few good tools.
除此之外,您还可能通过其他方式将错误写入脚本,从而导致无法登录防火墙的问题。这也可以通过在运行脚本之前使用一点技巧来解决。使用脚本语言和系统环境的全部功能可以证明非常强大,几乎所有经验丰富的 Unix 管理员以前都应该已经注意到这一点,这基本上也是我们在调试脚本时所做的一切。
Other than this, you may write bugs into your scripts in other ways as well, which can create the problem of being unable to login to the firewall. This can also be solved by using a little bit of cleverness before running the scripts at all. Using the full power of both the scripting language as well as the system environment can prove incredibly powerful, which almost all experienced Unix administrators should already have noticed from before, and this is basically all we do when debugging our scripts as well.
使用 bash 可以完成很多事情来帮助调试包含规则集的脚本。查找错误的首要问题之一是知道问题出现在哪一行。这可以通过两种不同的方式解决,或者使用 bash -x 标志,或者简单地输入一些 echo 语句来查找问题发生的位置。理想情况下,您可以使用 echo 语句在代码中定期添加类似以下 echo 语句的内容:
There are quite a few things that can be done with bash to help debugging your scripts containing the rulesets. One of the first problems with finding a bug is to know on which line the problem appears. This can be solved in two different ways, either using the bash -x flag, or by simply entering some echo statements to find the place where the problem happens. Ideally, you would, with the echo statement, add something like the following echo statement at regular intervals in the code:
...
echo“调试消息1”。
...
echo“调试消息2”。
...
...
echo "Debugging message 1."
...
echo "Debugging message 2."
...
就我而言,我通常使用几乎毫无价值的消息,只要它们中有一些独特的东西,这样我就可以通过简单的 grep 或在脚本文件中搜索来找到错误消息。现在,如果错误消息出现在“调试消息 1”之后。消息,但在“调试消息 2.”之前,那么我们就知道错误的代码行位于两条调试消息之间。正如您所理解的,bash 的想法并不是很糟糕,但至少很奇特,即即使之前的命令之一出现错误,也会继续执行命令。在 netfilter 中,这可能会给您带来一些非常有趣的问题。上面简单地使用echo语句来查找错误的想法非常简单,
In my case, I generally use pretty much worthless messages, as long as they have something in them that is unique so I can find the error message by a simple grep or search in the script file. Now, if the error message shows up after the "Debugging message 1." message, but before "Debugging message 2.", then we know that the erroneous line of code is somewhere in between the two debugging messages. As you can understand, bash has the not really bad, but at least peculiar, idea of continuing to execute commands even if there is an error in one of the commands before. In netfilter, this can cause some very interesting problems for you. The above idea of simply using echo statements to find the errors is extremely simple, but it is at the same time very nice since you can narrow the whole problem down to a single line of code and see what the problem is directly.
发现上述问题的第二种可能性是使用 -x 变量进行 bash,正如我们之前谈到的。这当然可能是一个小问题,特别是如果您的脚本很大并且控制台缓冲区不够大。-x 变量的含义非常简单,它告诉脚本将脚本中的每一行代码回显到 shell 的标准输出(通常是您的控制台)。您要做的就是更改脚本的正常起始行:
The second possibility to find the above problem is to use the -x variable to bash, as we spoke of before. This can of course be a minor problem, especially if your script is large, and if your console buffer isn't large enough. What the -x variable means is quite simple, it tells the script to just echo every single line of code in the script to the standard output of the shell (generally your console). What you do is to change your normal start line of the script from this:
#!/bin/bash
#!/bin/bash
进入下面的行:
Into the line below:
#!/bin/bash -x
#!/bin/bash -x
正如您将看到的,这会将您的输出从几行更改为输出上的大量数据。该代码向您显示了执行的每个命令行以及所有变量的值等,因此您不必尝试弄清楚代码到底在做什么。简而言之,执行的每一行也会输出到屏幕上。值得一看的一件事是 bash 输出的所有行都以 + 号为前缀。这使得从实际脚本中辨别错误或警告消息变得更容易,而不仅仅是一大堆输出。
As you will see, this changes your output from perhaps a couple of lines, to copious amounts of data on the output. The code shows you every single command line that is executed, and with the values of all the variables et cetera, so that you don't have to try and figure out exactly what the code is doing. Simply put, each line that gets executed is output to your screen as well. One thing that may be nice to see, is that all of the lines that bash outputs are prefixed by a + sign. This makes it a little bit easier to discern error or warning messages from the actual script, rather than just one big mesh of output.
-x 选项对于调试其他一些相当常见的问题也非常有趣,您可能会在使用更复杂的规则集时遇到这些问题。第一个是找出您认为的简单循环(例如 for、if 或 while 语句)究竟会发生什么?例如,我们来看一个例子。
The -x option is also very interesting for debugging a couple of other rather common problems that you may run into with a little bit more complex rulesets. The first of them is to find out exactly what happens with what you thought was a simple loop, such as an for, if or while statement? For example, let's look at an example.
#!/bin/bash
iptables=“/sbin/iptables”
$iptables -N output_int_iface
猫 /etc/configs/machines | 读取主机时;做
$iptables -N 输出-$host
$iptables -A output_int_iface -p tcp -d $host -j 输出-$host
猫 /etc/configs/${host}/ports | 当读取第2行时;做
$iptables -A 输出-$host -p tcp --dport $row2 -d $host -j 接受
完毕
完毕
#!/bin/bash
iptables="/sbin/iptables"
$iptables -N output_int_iface
cat /etc/configs/machines | while read host; do
$iptables -N output-$host
$iptables -A output_int_iface -p tcp -d $host -j output-$host
cat /etc/configs/${host}/ports | while read row2; do
$iptables -A output-$host -p tcp --dport $row2 -d $host -j ACCEPT
done
done
这套规则可能看起来很简单,但我们仍然遇到问题。通过使用简单的 echo 调试方法,我们得到了以下错误消息,我们知道这些错误消息来自上述代码。
This set of rules may look simple enough, but we continue to run into a problem with it. We get the following error messages that we know come from the above code by using the simple echo debugging method.
工作3:~#./test.sh
错误的参数“输出-”
尝试“iptables -h”或“iptables --help”以获取更多信息。
cat: /etc/configs//ports: 没有这样的文件或目录
work3:~# ./test.sh
Bad argument `output-'
Try `iptables -h' or 'iptables --help' for more information.
cat: /etc/configs//ports: No such file or directory
所以我们打开 bash 的 -x 选项并查看输出。输出如下所示,正如您所看到的,其中发生了一些非常奇怪的事情。有几个命令的 $host 和 $row2 变量没有被替换。仔细观察,我们发现只是代码的最后一次迭代导致了问题。要么我们犯了程序错误,要么数据有问题。在这种情况下,这是一个简单的数据错误,其中在文件末尾包含一个额外的换行符。这会导致循环最后一次迭代,而这是不应该的。只需删除文件的尾部换行符即可解决问题。这可能不是一个非常优雅的解决方案,但对于私人工作来说应该足够了。否则,
So we turn on the -x option to bash and look at the output. The output is shown below, and as you can see there is something very weird going on in it. There are a couple of commands where the $host and $row2 variables are replaced by nothing. Looking closer, we see that it is only the last iteration of code that causes the trouble. Either we have done a programmatical error, or there is something strange with the data. In this case, it is a simple error with the data, which contains a single extra linebreak at the end of the file. This causes the loop to iterate one last time, which it shouldn't. Simply remove the trailing linebreak of the file, and the problem is solved. This may not be a very elegant solution, but for private work it should be enough. Otherwise, you could add code that looks to see that there is actually some data in the $host and $row2 variables.
工作3:~#./test.sh
+ iptables=/sbin/iptables
+ /sbin/iptables -N output_int_iface
+ 猫 /etc/configs/machines
+ 读取主机
+ /sbin/iptables -N 输出-sto-as-101
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-101 -j 输出sto-as-101
+ 猫 /etc/configs/sto-as-101/ports
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-101 -p tcp --dport 21 -d sto-as-101 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-101 -p tcp --dport 22 -d sto-as-101 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-101 -p tcp --dport 23 -d sto-as-101 -j 接受
+ 读取第2行
+ 读取主机
+ /sbin/iptables -N 输出-sto-as-102
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-102 -j 输出sto-as-102
+ 猫 /etc/configs/sto-as-102/ports
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-102 -p tcp --dport 21 -d sto-as-102 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-102 -p tcp --dport 22 -d sto-as-102 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-102 -p tcp --dport 23 -d sto-as-102 -j 接受
+ 读取第2行
+ 读取主机
+ /sbin/iptables -N 输出-sto-as-103
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-103 -j 输出-sto-as-103
+ 猫 /etc/configs/sto-as-103/ports
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-103 -p tcp --dport 21 -d sto-as-103 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-103 -p tcp --dport 22 -d sto-as-103 -j 接受
+ 读取第2行
+ /sbin/iptables -A 输出 sto-as-103 -p tcp --dport 23 -d sto-as-103 -j 接受
+ 读取第2行
+ 读取主机
+ /sbin/iptables -N 输出-
+ /sbin/iptables -A output_int_iface -p tcp -d -j 输出-
错误的参数“输出-”
尝试“iptables -h”或“iptables --help”以获取更多信息。
+ cat /etc/configs//端口
cat: /etc/configs//ports: 没有这样的文件或目录
+ 读取第2行
+ 读取主机
work3:~# ./test.sh
+ iptables=/sbin/iptables
+ /sbin/iptables -N output_int_iface
+ cat /etc/configs/machines
+ read host
+ /sbin/iptables -N output-sto-as-101
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-101 -j output-sto-as-101
+ cat /etc/configs/sto-as-101/ports
+ read row2
+ /sbin/iptables -A output-sto-as-101 -p tcp --dport 21 -d sto-as-101 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-101 -p tcp --dport 22 -d sto-as-101 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-101 -p tcp --dport 23 -d sto-as-101 -j ACCEPT
+ read row2
+ read host
+ /sbin/iptables -N output-sto-as-102
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-102 -j output-sto-as-102
+ cat /etc/configs/sto-as-102/ports
+ read row2
+ /sbin/iptables -A output-sto-as-102 -p tcp --dport 21 -d sto-as-102 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-102 -p tcp --dport 22 -d sto-as-102 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-102 -p tcp --dport 23 -d sto-as-102 -j ACCEPT
+ read row2
+ read host
+ /sbin/iptables -N output-sto-as-103
+ /sbin/iptables -A output_int_iface -p tcp -d sto-as-103 -j output-sto-as-103
+ cat /etc/configs/sto-as-103/ports
+ read row2
+ /sbin/iptables -A output-sto-as-103 -p tcp --dport 21 -d sto-as-103 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-103 -p tcp --dport 22 -d sto-as-103 -j ACCEPT
+ read row2
+ /sbin/iptables -A output-sto-as-103 -p tcp --dport 23 -d sto-as-103 -j ACCEPT
+ read row2
+ read host
+ /sbin/iptables -N output-
+ /sbin/iptables -A output_int_iface -p tcp -d -j output-
Bad argument `output-'
Try `iptables -h' or 'iptables --help' for more information.
+ cat /etc/configs//ports
cat: /etc/configs//ports: No such file or directory
+ read row2
+ read host
您遇到的第三个也是最后一个问题可以通过 -x 选项部分解决,那就是如果您通过 SSH 执行防火墙脚本,并且控制台在执行脚本的过程中挂起,并且控制台根本不会运行。不要回来,也无法再次通过 SSH 连接。在 99.9% 的情况下,这意味着脚本中的一些规则存在某种问题。通过打开 -x 选项,您将准确地看到脚本在哪一行被锁定,希望至少是这样。不幸的是,在某些情况下情况并非如此。例如,如果脚本设置了阻止传入流量的规则,但由于 ssh/telnet 服务器首先将 echo 作为传出流量发送,netfilter 将记住该连接,该怎么办?
The third and final problem you run into that can be partially solved with the help of the -x option is if you are executing the firewall script via SSH, and the console hangs in the middle of executing the script, and the console simply won't come back, nor are you able to connect via SSH again. In 99.9% of the cases, this means there is some kind of problem inside the script with a couple of the rules. By turning on the -x option, you will see exactly at which line the script locks dead, hopefully at least. There are a couple of circumstances where this is not true, unfortunately. For example, what if the script sets up a rule that blocks incoming traffic, but since the ssh/telnet server sends the echo first as outgoing traffic, netfilter will remember the connection, and hence allow the incoming traffic anyways if you have a rule above that handles connection states.
正如您所看到的,最终调试规则集的全部内容可能会变得相当复杂。然而,这也并非不可能。您可能还注意到,例如,如果您通过 SSH 在防火墙上远程工作,则当您加载错误的规则集时,防火墙可能会挂起。在这种情况下,还可以做一件事来挽救局面。Cron 是拯救你的好方法。例如,假设您正在 50 公里外的防火墙上工作,您添加一些规则,删除一些其他规则,然后删除并插入新的更新规则集。防火墙已死,你无法访问它。解决此问题的唯一方法是转到防火墙的物理位置并从那里解决问题,除非您已采取预防措施!
As you can see, it can become quite complex to debug your ruleset to its full extent in the end. However, it is not impossible at all. You may also have noticed, if you have worked remotely on your firewalls via SSH, for example, that the firewall may hang when you load bad rulesets. There is one more thing that can be done to save the day in these circumstances. Cron is an excellent way of saving your day. For example, say you are working on a firewall 50 kilometers away, you add some rules, delete some others, and then delete and insert the new updated ruleset. The firewall locks dead, and you can't reach it. The only way of fixing this is to go to the firewall's physical location and fix the problem from there, unless you have taken precautions that is!
针对锁定的防火墙,您可以采取的最佳预防措施之一是简单地使用 cron 添加一个每 5 分钟左右运行一次的脚本,以重置防火墙,然后在确定安装正常后删除该 cron 行。cron 行可能类似于下面的行,并使用命令 crontab -e 输入。
One of the best precautions you may take against a locked down firewall is to simply use cron to add a script that is run every 5 minutes or so that resets the firewall, and then remove that cron line once you are sure the installation works fine. The cron line may look something like the one below and be entered with the command crontab -e.
*/5 * * * * /etc/init.d/rc.flush-iptables.sh stop
*/5 * * * * /etc/init.d/rc.flush-iptables.sh stop
在开始执行您期望会或可能冻结您正在处理的服务器的操作之前,请绝对确保该线路确实可以工作并执行您期望的操作。
Make absolutely sure, that the line will actually work and do what you expect it to do before you start doing something you expect will or may freeze the server you are working on.
另一个经常用于调试脚本的工具是系统日志工具。这是记录由大量不同程序创建的所有日志消息的工具。事实上,几乎所有大型程序都支持 syslog 日志记录,包括内核。发送到 syslog 的所有消息都设置了两个非常重要的基本变量,即设施和日志级别/优先级,这两个变量非常重要。
Another tool that is constantly used to debug your scripts is the syslog facility. This is the facility that logs all log-messages created by a ton of different programs. In fact, almost all large programs support syslog logging, including the kernel. All messages sent to syslog have two basic variables set to them that are very important to remember, the facility and the log level/priority.
该设施告诉系统日志服务器日志条目来自哪个设施以及在哪里记录它。有几个指定的设施,但现在讨论的一个是 Kern 设施,或者也可以称为内核设施。所有 netfilter 生成的消息都使用此工具发送。
The facility tells the syslog server from which facility the log entry came from, and where to log it. There are several specified facilities, but the one in question right now is the Kern facility, or kernel facility as it may also be called. All netfilter generated messages are sent using this facility.
日志级别告诉 syslog 日志消息的优先级有多高。有几个可以使用的优先级,如下所列。
The log level tells syslog how high priority the log messages have. There are several priorities that can be used, listed below.
调试
debug
信息
info
注意
notice
警告
warning
呃
err
暴击
crit
警报
alert
新兴
emerg
根据这些优先级,我们可以使用 syslog.conf 将它们发送到不同的日志文件。例如,要将具有警告优先级的 kern 设施中的所有消息发送到名为/var/log/kernwarnings 的文件,我们可以执行如下操作。该行应该进入 /etc/syslog.conf。
Depending on these priorities, we can send them to different log files using the syslog.conf. For example, to send all messages from the kern facility with warning priority to a file called /var/log/kernwarnings, we could do as shown below. The line should go into the /etc/syslog.conf.
kern.warning /var/log/kernwarnings
kern.warning /var/log/kernwarnings
正如您所看到的,这非常简单。现在您有望在文件 /var/log/kernwarnings中找到您的 netfilter 日志(重新启动或 HUP 系统日志服务器后)。当然,这也取决于您在 netfilter 日志记录规则中设置的日志级别。可以使用 --log-level 选项设置日志级别。
As you can see, it's quite simple. Now you will hopefully find your netfilter logs in the file /var/log/kernwarnings (after restarting, or HUP'ing the syslog server). Of course, this also depends on what log levels you set in your netfilter logging rules. The log level can be set there with the --log-level option.
输入到此文件中的日志将为您提供有关您希望通过规则集中的特定日志规则记录的所有数据包的信息。通过这些,您可以查看是否存在任何具体问题。例如,您可以在所有链的末尾设置日志规则,以查看是否有任何数据包跨越链的边界。日志条目可能类似于下面的示例,并且包含大量信息,如您所见。
The logs entered into this file will give you information about all the packets that you wish to log via specific log rules in the ruleset. With these, you can see if there is anything specific that goes wrong. For example, you can set logrules in the end of all the chains to see if there are any packets that are carried over the boundary of the chains. A log entry may look something like the example below, and include quite a lot of information as you can see.
10 月 23 日 17:09:34 本地主机内核:IPT INPUT 数据包死亡:IN=eth1 OUT=
MAC=08:00:09:cd:f2:27:00:20:1a:11:3d:73:08:00 SRC=200.81.8.14 DST=217.215.68.146
LEN=78 TOS=0x00 PREC=0x00 TTL=110 ID=12818 PROTO=UDP SPT=1027 DPT=137 LEN=58
Oct 23 17:09:34 localhost kernel: IPT INPUT packet died: IN=eth1 OUT=
MAC=08:00:09:cd:f2:27:00:20:1a:11:3d:73:08:00 SRC=200.81.8.14 DST=217.215.68.146
LEN=78 TOS=0x00 PREC=0x00 TTL=110 ID=12818 PROTO=UDP SPT=1027 DPT=137 LEN=58
正如您所理解的,系统日志在调试规则集时确实可以为您提供帮助。查看这些日志可能会帮助您了解为什么您想要打开的某些端口不起作用。
As you can understand, syslog can really help you out when debugging your rulesets. Looking at these logs may help you understand why some port that you wanted to open doesn't work.
有时 iptables 很难调试,因为 iptables 本身的错误消息在任何时候都不是很用户友好。因此,最好查看一下从 iptables 中获得的最常见错误消息以及获得这些消息的原因。
Iptables can be rough to debug sometimes, since the error messages from iptables itself aren't very user friendly at all times. For this reason, it may be a good idea to take a look at the most common error messages you can get from iptables, and why you may have gotten them.
首先要查看的错误消息之一是“Unknown arg”错误。出现这种情况可能有多种原因。例如,请看下面。
One of the first error messages to look at is the "Unknown arg" error. This may show up for several reasons. For example, look below.
work3:~# iptables -A 输入 --dport 67 -j 接受
iptables v1.2.9:未知参数“--dport”
尝试“iptables -h”或“iptables --help”以获取更多信息。
work3:~# iptables -A INPUT --dport 67 -j ACCEPT
iptables v1.2.9: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.
这个错误比正常错误更容易解决,因为我们只使用了一个参数。通常,您可能使用了很长的命令并收到此错误消息。上述场景中的问题是我们忘记使用 --protocol 匹配,因此, --dport 匹配对我们不可用。添加 --protocol 匹配也可以解决此匹配中的问题。绝对确保您没有遗漏使用特定匹配所需的任何特殊先决条件。
This error is simpler than normal to solve, since we have only used a single argument. Normally, you may have used a long, long command and get this error message. The problem in the above scenario is that we have forgotten to use the --protocol match, and because of that, the --dport match isn't available to us. Adding the --protocol match would also solve the problem in this match. Make absolutely certain that you are not missing any special preconditions that are required to use a specific match.
另一个非常常见的错误是,如果您在命令行中的某处漏掉了破折号 (-),如下所示。正确的解决方案是简单地添加破折号,命令就会起作用。
Another very common error is if you miss a dash (-) somewhere in the command line, like below. The proper solution is to simply add the dash, and the command will work.
work3:~# iptables -A INPUT --protocol tcp -dport 67 -j ACCEPT
错误的参数“67”
尝试“iptables -h”或“iptables --help”以获取更多信息。
work3:~# iptables -A INPUT --protocol tcp -dport 67 -j ACCEPT
Bad argument `67'
Try `iptables -h' or 'iptables --help' for more information.
最后,还有简单的拼写错误,这也很常见。如下所示。您会注意到,错误消息与您忘记向规则添加另一个先决条件匹配时的错误消息完全相同,因此需要仔细检查。
And finally, there is the simple misspelling, which is rather common as well. This is shown below. The error message, as you will notice, is exactly the same as when you forget to add another prerequisite match to the rule, so it needs to be carefully looked into.
work3:~# iptables -A INPUT --protocol tcp --destination-ports 67 -j ACCEPT
iptables v1.2.9:未知参数“--destination-ports”
尝试“iptables -h”或“iptables --help”以获取更多信息。
work3:~# iptables -A INPUT --protocol tcp --destination-ports 67 -j ACCEPT
iptables v1.2.9: Unknown arg `--destination-ports'
Try `iptables -h' or 'iptables --help' for more information.
上面显示的“Unknown arg”错误还有一个可能的原因。如果您可以看到参数写得很完美,并且先决条件中没有可能存在错误,则目标/匹配/表可能根本没有编译到内核中。例如,假设我们忘记将过滤器表支持编译到内核中,则看起来像这样:
There is also one more possible cause for the "Unknown arg" error shown above. If you can see that the argument is perfectly written, and no possible errors in the prerequisites, there is a possibility that the target/match/table was simply not compiled into the kernel. For example, let's say we forgot to compile the filter table support into the kernel, this would then look something like this:
work3:~# iptables -A 输入 -j 接受
iptables v1.2.9:无法初始化 iptables 表“过滤器”:表不存在
(需要insmod吗?)
也许 iptables 或您的内核需要升级。
work3:~# iptables -A INPUT -j ACCEPT
iptables v1.2.9: can't initialize iptables table `filter': Table does not exist
(do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
通常,iptables 应该能够自动 modprobe 不在内核中的特定模块,因此这通常表明在使用新内核重新启动后没有执行正确的 depmod,或者您可能只是忘记了模块。如果有问题的模块是匹配的,则错误消息会更加神秘且难以理解。例如,查看此错误消息。
Normally, iptables should be able to automatically modprobe a specific module that isn't already inside the kernel, so this is generally a sign of either not having done a proper depmod after restarting with the new kernel, or you may simply have forgotten about the module(s). If the problematic module would be a match instead, the error message would be a little bit more cryptic and hard to understand. For example, look at this error message.
work3:~# iptables -A INPUT -m 状态
--state 已建立 -j 接受
iptables:没有该名称的链/目标/匹配
work3:~# iptables -A INPUT -m state
--state ESTABLISHED -j ACCEPT
iptables: No chain/target/match by that name
在这种情况下,我们忘记编译状态模块,正如您所看到的,错误消息不是很好且易于理解。但它确实给了你一个提示,告诉你哪里出了问题。最后,我们再次遇到同样的错误,但这一次,目标丢失了。正如您从查看错误消息中了解到的那样,它变得相当复杂,因为这两个错误的错误消息完全相同(缺少匹配和/或目标)。
In this case, we forgot to compile the state module, and as you can see the error message isn't very nice and easy to understand. But it does give you a hint at what is wrong. Finally, we have the same error again, but this time, the target is missing. As you understand from looking at the error message, it get's rather complicated since it is the exact same error message for both errors (missing match and/or target).
work3:~# iptables -A INPUT -m 状态
--state 已建立 -j 拒绝
iptables:没有该名称的链/目标/匹配
work3:~# iptables -A INPUT -m state
--state ESTABLISHED -j REJECT
iptables: No chain/target/match by that name
要查看我们是否只是忘记了 depmod,或者模块是否确实丢失,最简单的方法是查看模块应该所在的目录。这是/lib/modules/2.6.4/kernel/net/ipv4/netfilter 目录。所有以大写字母编写的 ipt_* 文件都是目标,而所有以小写字母编写的文件都是匹配项。例如,ipt_REJECT.ko 是目标,而 ipt_state.ko 是匹配项。
The easiest way to see if we have simply forgotten to depmod, or if the module is actually missing is to look in the directory where the modules should be. This is the /lib/modules/2.6.4/kernel/net/ipv4/netfilter directory. All ipt_* files that are written in uppercase letters are targets, while all the ones with lowercase letters are matches. For example, ipt_REJECT.ko is a target, while the ipt_state.ko is a match.
在 2.4 内核及更早版本中,所有内核模块的文件扩展名为 .o,在 2.6 内核中更改为 .ko。 In 2.4 kernels and older, the file extension for all kernel modules was .o, which changed to .ko for files in the 2.6 kernels. |
从 iptables 本身获得帮助的另一种方法是简单地注释掉脚本中的整个链,看看是否可以解决问题。这是一种最后的问题解决方案,如果您甚至不知道哪个链导致了问题,这可能会非常有效。通过删除整个链并简单地设置默认策略 ACCEPT,然后进行测试,如果效果更好,那么这就是导致问题的链。如果效果还不好,那就是另外一条链了,你可以继续去别处寻找问题。
Another way of getting help from iptables itself is to simply comment out a whole chain from your script to see if that fixes the problem. This is kind of a last resort problem solver, that may be very effective if you don't even know which chain is causing the problem. By removing the whole chain and simply setting a default policy of ACCEPT, and then testing, if it works better, then this is the chain that is causing the problems. If it doesn't work better, then it is another chain, and you can go on to find the problem elsewhere.
当然,在调试防火墙脚本时,还有其他可能非常有用的工具。本节将简要介绍最常用的工具,用于快速了解防火墙从各个侧面(内部、外部等)的外观。我在这里选择的工具是 nmap 和 nessus 工具。
There are of course other tools that may be extremely useful when debugging your firewall scripts. This section will briefly touch the most common tools used to find out fast how your firewall looks from all sides of it (inside, outside, etc). The tools I have chosen here are the nmap and nessus tools.
Nmap 是一个出色的工具,可以从纯粹的防火墙角度查看,并找出哪些端口是开放的以及更多底层信息。它支持操作系统指纹、多种不同的端口扫描方法、IPv6 和 IPv4 支持以及网络扫描。
Nmap is an excellent tool for looking at the pure firewall perspective, and to find out which ports are open and more low level information. It has support for OS fingerprinting, several different port scanning methods, IPv6 and IPv4 support and network scanning.
扫描的基本形式是通过非常简单的命令行语法完成的。不要忘记使用 -p 选项指定要扫描的端口,例如 -p 1-1024。作为一个例子,请看下面。
The basic form of scanning is done with a very simple commandline syntax. Don't forget to specify which ports to scan through with the -p option, for example -p 1-1024. As an example, take a look below.
blueflux@work3:~$ nmap -p 1-1024 192.168.0.1
于 2004 年 3 月 18 日 17:19 CET 启动 nmap 3.50 ( http://www.insecure.org/nmap/ )
防火墙上有趣的端口(192.168.0.1):
(扫描到但下面未显示的1021端口处于状态:关闭)
港口国服务
22/tcp 打开 ssh
25/tcp 打开smtp
587/tcp 开放提交
Nmap 运行完成 - 3.877 秒内扫描 1 个 IP 地址(1 个主机)
blueflux@work3:~$ nmap -p 1-1024 192.168.0.1
Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-03-18 17:19 CET
Interesting ports on firewall (192.168.0.1):
(The 1021 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
587/tcp open submission
Nmap run completed -- 1 IP address (1 host up) scanned in 3.877 seconds
它还能够通过操作系统指纹识别来自动猜测扫描主机的操作系统。虽然指纹识别需要 root 权限,但用它来了解大多数人对主机的看法也可能非常有趣。使用操作系统指纹识别可能类似于下面列出的示例。
It is also able to automatically guess the operating system of the scanned host by doing OS fingerprinting. Fingerprinting requires root privileges though, but it may also be very interesting to use to find out what most people will think of the host. Using OS fingerprinting may look something like the example listing below.
work3:/home/blueflux# nmap -O -p 1-1024 192.168.0.1
于 2004 年 3 月 18 日 17:38 CET 启动 nmap 3.50 ( http://www.insecure.org/nmap/ )
防火墙上有趣的端口(192.168.0.1):
(扫描到但下面未显示的1021端口处于状态:关闭)
港口国服务
22/tcp 打开 ssh
25/tcp 打开smtp
587/tcp 开放提交
设备类型:通用
运行:Linux 2.4.X|2.5.X
操作系统详细信息:Linux 内核 2.4.0 - 2.5.20
正常运行时间 6.201 天(自 2004 年 3 月 12 日星期五 12:49:18 起)
Nmap 运行已完成 -- 在 14.303 秒内扫描 1 个 IP 地址(1 个主机已启动)
work3:/home/blueflux# nmap -O -p 1-1024 192.168.0.1
Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2004-03-18 17:38 CET
Interesting ports on firewall (192.168.0.1):
(The 1021 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
587/tcp open submission
Device type: general purpose
Running: Linux 2.4.X|2.5.X
OS details: Linux Kernel 2.4.0 - 2.5.20
Uptime 6.201 days (since Fri Mar 12 12:49:18 2004)
Nmap run completed -- 1 IP address (1 host up) scanned in 14.303 seconds
如您所见,操作系统指纹识别并不完美,但它将帮助您和攻击者缩小范围。因此,您了解一下也很有趣。最好的办法是为攻击者提供尽可能少的材料来获得正确的指纹,通过这些信息,您将非常清楚地了解攻击者对您的操作系统的了解。
OS fingerprinting isn't perfect, as you can see, but it will help narrow it down, both for you, and for the attacker. Hence, it is interesting for you to know as well. The best thing to do, is to give as little material as possible for the attacker to get a proper fingerprint on, and with this information you will know fairly well what the attacker knows about your OS as well.
Nmap还附带了一个可以使用的图形用户界面,称为nmapfe(Nmap前端)。它是 nmap 程序的一个优秀前端,如果您知道需要更复杂的搜索,您可能希望使用它。有关示例屏幕截图,请看下面。
Nmap also comes with a graphical user interface that can be used, called the nmapfe (Nmap Front End). It is an excellent frontend of the nmap program, and if you know that you will need a little bit more complicated searches, you may wish to use it. For an example screenshot, take a look below.
当然,nmap工具的用法远不止这些,你可以在nmap主页上找到更多相关信息。有关更多信息,请查看Nmap资源。
Of course, the nmap tool has more usages than this, which you can find out more about on the nmap homepage. For more information, take a look at the Nmap resources.
正如您可能理解的,这是一个很好的工具,可以用来测试您的主机,并找出哪些端口实际打开,哪些端口没有打开。例如,完成设置后,使用 nmap 来查看您是否确实成功地完成了您想做的事情。您是否从正确的端口获得了正确的响应,等等。
As you may understand, this is an excellent tool to test your host with, and to find out which ports are actually open and which are not. For example, after finishing your setup, use nmap to see if you have actually succeeded in doing what you wanted to do. Do you get the correct responses from the correct ports, and so on.
虽然 nmap 更像是一个低级扫描器,显示开放端口等,但 nessus 程序是一个真正的安全扫描器。Nmap 尝试连接到不同的端口,并最多找出不同服务器正在运行的版本。Nessus 更进一步,通过查找所有开放端口,找出该特定端口上正在运行的内容、正在运行的程序和版本,然后测试对该程序的不同安全威胁,最后创建所有的完整报告可用的安全威胁。
While nmap is more of a low level scanner, showing open ports etcetera, the nessus program is an actual security scanner. Nmap tries to connect to different ports, and to find out at most, what kind of version the different servers are running. Nessus takes this a step further, by finding all open ports, finding out what is running on that specific port, what program and which version is running, and then testing for different security threats to that program, and finally creating a complete report of all the security threats that are available.
正如您所理解的,这是一个非常有用的工具,可以帮助您了解有关您的主机的更多信息。该程序是以服务器客户端方式构建的,因此通过使用外部 nessus 守护程序或内部守护程序,应该相当容易从外部找到有关防火墙的更多信息。该客户端是一个图形用户界面,您可以在其中登录 nessus 守护程序、设置您的设置并指定您要扫描漏洞的主机。生成的报告可能类似于以下示例。
As you can understand, this is an extremely useful tool to find out more about your host. The program is built up in a server client way, so it should be fairly easy to find out more about your firewall from the outside by using an external nessus daemon, or internal for that matter. The client is a graphical user interface where you login to the nessus daemon, set your settings, and specify which host you would like to scan for vulnerabilities. The generated report may look something like in the example below.
然而,使用 Nessus 时应谨慎,因为它可能会使指定攻击的机器或服务崩溃。幸运的是,那些可能导致机器崩溃的攻击默认情况下会被关闭。 Nessus should be used with some caution however, since it can crash a machine or a service that it is specified to attack. Those attacks that risk crashing a machine are per default turned off luckily. |
在本章中,我们详细介绍了可用于调试防火墙脚本的不同技术。防火墙脚本的调试可能会变得相当乏味且冗长,但这是必要的。如果您在执行此操作时使用一些简单的小步骤,最终也会变得非常容易。我们特别研究了以下技术:
In this chapter we have looked in detail at different techniques you can use to debug your firewall scripts. Debugging of firewall scripts can become rather tedious and longwinded, however it is a necessity. If you use some small simple steps while doing this, it can become very easy in the end as well. We have looked at the following techniques in particular:
Bash 帮助调试
Bash help in debugging
适合调试的系统工具
System tools fit for debugging
iptables调试
Iptables debugging
其他调试工具
Other tools for debugging
本章将介绍防火墙设置示例以及脚本文件的外观。我们使用了一种基本设置,并更深入地研究了它的工作原理以及我们在其中所做的事情。这应该用于了解如何解决不同问题以及在实际使用脚本之前可能需要考虑的内容。它可以按原样使用,并对变量进行一些更改,但不建议这样做,因为它可能无法与您的网络设置完美配合。然而,只要您有一个非常基本的设置,只需进行一些修复,它很可能会运行得非常顺利。
This chapter will deal with an example firewall setup and how the script file could look. We have used one of the basic setups and dug deeper into how it works and what we do in it. This should be used to get a basic idea on how to solve different problems and what you may need to think about before actually putting your scripts to work. It could be used as is with some changes to the variables, but is not suggested since it may not work perfectly together with your network setup. As long as you have a very basic setup however, it will very likely run quite smooth with just a few fixes to it.
请注意,可能有更有效的方法来制定规则集,但是,编写脚本是为了提高可读性,以便每个人都可以理解它,而无需在阅读本文之前了解太多 BASH 脚本 note that there might be more efficient ways of making the rule-set, however, the script has been written for readability so that everyone can understand it without having to know too much BASH scripting before reading this |
好的,您已完成所有设置并准备好查看示例配置脚本。如果你已经走到这一步了,你至少应该是这样的。此示例rc.firewall.txt (也包含在示例脚本代码库 附录中)相当大,但其中没有很多注释。我建议您不要寻找注释,而是通读脚本文件,对它的外观有一个基本的了解,然后返回此处以了解整个脚本的具体情况。
OK, so you have everything set up and are ready to check out an example configuration script. You should at least be if you have come this far. This example rc.firewall.txt (also included in the Example scripts code-base appendix) is fairly large but not a lot of comments in it. Instead of looking for comments, I suggest you read through the script file to get a basic hum about how it looks, and then you return here to get the nitty gritty about the whole script.
在示例rc.firewall.txt中您应该注意的第一部分是配置部分。应该始终更改它,因为它包含对您的实际配置至关重要的信息。例如,您的 IP 地址总是会发生变化,因此可以在此处获取。$INET_IP 应该始终是一个完全有效的 IP 地址,如果您有一个(如果没有,那么您可能应该仔细查看 rc.DHCP.firewall.txt ,但是,请继续阅读,因为此脚本将引入很多有趣的内容无论如何)。此外,$INET_IFACE 变量应指向用于 Internet 连接的实际设备。这可能是 eth0、eth1、ppp0、tr0 等,仅举几个可能的设备名称。
The first section you should note within the example rc.firewall.txt is the configuration section. This should always be changed since it contains the information that is vital to your actual configuration. For example, your IP address will always change, hence it is available here. The $INET_IP should always be a fully valid IP address, if you got one (if not, then you should probably look closer at the rc.DHCP.firewall.txt, however, read on since this script will introduce a lot of interesting stuff anyways). Also, the $INET_IFACE variable should point to the actual device used for your Internet connection. This could be eth0, eth1, ppp0, tr0, etc just to name a few possible device names.
该脚本不包含 DHCP 或 PPPoE 的任何特殊配置选项,因此这些部分为空。对于所有空白部分也是如此,但是它们保留在那里,以便您可以更有效地发现脚本之间的差异。如果您需要这些部分,那么您始终可以创建不同脚本的混合,或者(做好准备)从头开始创建自己的脚本。
This script does not contain any special configuration options for DHCP or PPPoE, hence these sections are empty. The same goes for all sections that are empty, they are, however, left there so you can spot the differences between the scripts in a more efficient way. If you need these parts, then you could always create a mix of the different scripts, or (brace yourself) create your own from scratch.
局域网部分包含 LAN 的大部分必要配置选项。例如,您需要指定连接 LAN 的物理接口的 IP 地址、LAN 使用的 IP 范围以及盒子连接 LAN 的接口。
The Local Area Network section contains most of the configuration options for your LAN, which are necessary. For example, you need to specify the IP address of the physical interface connected to the LAN as well as the IP range which the LAN uses and the interface that the box is connected to the LAN through.
另外,正如您所看到的,还有一个本地主机配置部分。我们确实提供了它,但是您 99% 确定不会更改此部分中的任何值,因为您几乎总是使用 127.0.0.1 IP 地址,并且该接口几乎肯定会被命名为 lo。此外,在本地主机配置下方,您会发现与 iptables 有关的简短部分。主要是,此部分仅包含 $IPTABLES 变量,该变量将脚本指向 iptables 应用程序的确切位置。这可能会有所不同,手动编译 iptables 包时的默认位置是/usr/local/sbin/iptables。然而,许多发行版将实际应用程序放在另一个位置,例如/usr/sbin/iptables等。
Also, as you may see there is a Localhost configuration section. We do provide it, however you will with 99% certainty not change any of the values within this section since you will almost always use the 127.0.0.1 IP address and the interface will almost certainly be named lo. Also, just below the Localhost configuration, you will find a brief section that pertains to the iptables. Mainly, this section only consists of the $IPTABLES variable, which will point the script to the exact location of the iptables application. This may vary a bit, and the default location when compiling the iptables package by hand is /usr/local/sbin/iptables. However, many distributions put the actual application in another location such as /usr/sbin/iptables and so on.
首先,我们通过发出 /sbin/depmod -a 命令来确保模块依赖项文件是最新的。之后,我们加载该脚本所需的模块。始终避免加载不需要的模块,并且如果可能的话,尽量避免放置模块,除非您将要使用它们。这是出于安全原因,因为以这种方式制定附加规则需要一些额外的努力。现在,例如,如果您想要支持 LOG、REJECT 和 MASQUERADE 目标,并且不将其静态编译到内核中,我们将按如下方式加载这些模块:
First, we see to it that the module dependencies files are up to date by issuing a /sbin/depmod -a command. After this we load the modules that we will require for this script. Always avoid loading modules that you do not need, and if possible try to avoid having modules lying around at all unless you will be using them. This is for security reasons, since it will take some extra effort to make additional rules this way. Now, for example, if you want to have support for the LOG, REJECT and MASQUERADE targets and don't have this compiled statically into your kernel, we load these modules as follows:
/sbin/insmod ipt_LOG
/sbin/insmod ipt_REJECT
/sbin/insmod ipt_MASQUERADE
/sbin/insmod ipt_LOG
/sbin/insmod ipt_REJECT
/sbin/insmod ipt_MASQUERADE
在这些脚本中,我们强制加载模块,这可能会导致加载模块失败。如果模块加载失败,可能取决于很多因素,并且会生成错误消息。如果一些更基本的模块无法加载,其最大可能的错误是该模块或功能被静态编译到内核中。有关此主题的更多信息,请阅读常见问题和问题附录中的加载模块问题部分。 In these scripts we forcedly load the modules, which could lead to failures of loading the modules. If a module fails to load, it could depend upon a lot of factors, and it will generate an error message. If some of the more basic modules fail to load, its biggest probable error is that the module, or functionality, is statically compiled into the kernel. For further information on this subject, read the Problems loading modules section in the Common problems and questions appendix. |
接下来是加载 ipt_owner 模块的选项,例如,该模块可用于仅允许某些用户进行某些连接等。在本示例中我不会使用该模块,但基本上,您可以只允许 root 进行 FTP 和 HTTP 连接到 redhat.com 并删除所有其他的。您还可以禁止除您自己的用户和 root 之外的所有用户从您的盒子连接到互联网。对于其他人来说可能很无聊,但您会更安全地抵御黑客攻击和黑客仅使用您的主机作为中间主机的攻击。有关 ipt_owner 匹配的更多信息,请参阅如何构建规则一章中的 所有者匹配部分 。
Next is the option to load ipt_owner module, which could for example be used to only allow certain users to make certain connections, etc. I will not use that module in this example but basically, you could allow only root to do FTP and HTTP connections to redhat.com and DROP all the others. You could also disallow all users but your own user and root to connect from your box to the Internet. Might be boring for others, but you will be a bit more secure to bouncing hacker attacks and attacks where the hacker will only use your host as an intermediate host. For more information about the ipt_owner match, look at the Owner match section within the How a rule is built chapter.
我们还可以在此处为状态匹配代码加载额外的模块。所有扩展状态匹配代码和连接跟踪代码的模块都称为 ip_conntrack_* 和 ip_nat_*。连接跟踪助手是特殊的模块,告诉内核如何正确跟踪特定的连接。如果没有这些所谓的帮助程序,内核在尝试跟踪特定连接时将不知道要查找什么。另一方面,NAT 帮助程序是连接跟踪帮助程序的扩展,它告诉内核在特定数据包中查找什么以及如何转换这些数据包,以便连接真正起作用。例如,FTP 根据定义是一个复杂的协议,它在数据包的实际负载中发送连接信息。因此,如果您的一台 NAT 设备连接到 Internet 上的 FTP 服务器,它会在数据包的有效负载中发送自己的本地网络 IP 地址,并告诉 FTP 服务器连接到该 IP 地址。由于此本地网络地址在您自己的网络之外无效,因此 FTP 服务器将不知道如何处理它,因此连接将中断。FTP NAT 帮助程序在这些连接中执行所有转换,因此 FTP 服务器实际上知道连接到哪里。同样的情况也适用于 DCC 文件传输(发送)和聊天。创建此类连接需要在 IRC 协议内发送 IP 地址和端口,这又需要进行一些转换。如果没有这些助手,一些 FTP 和 IRC 的东西无疑可以工作,但是,其他一些东西将无法工作。例如,您可能能够通过 DCC 接收文件,但无法发送文件。这是由 DCC 启动连接的方式决定的。首先,您告诉接收者您要发送文件以及他应该连接到哪里。如果没有助手,DCC 连接看起来就像是希望接收者连接到接收者自己的本地网络上的某个主机。换句话说,整个连接将会被破坏。然而,相反,它会完美地工作,因为发件人(很可能)会为您提供正确的连接地址。
We may also load extra modules for the state matching code here. All modules that extend the state matching code and connection tracking code are called ip_conntrack_* and ip_nat_*. Connection tracking helpers are special modules that tell the kernel how to properly track the specific connections. Without these so called helpers, the kernel would not know what to look for when it tries to track specific connections. The NAT helpers on the other hand, are extensions of the connection tracking helpers that tell the kernel what to look for in specific packets and how to translate these so the connections will actually work. For example, FTP is a complex protocol by definition, and it sends connection information within the actual payload of the packet. So, if one of your NATed boxes connect to a FTP server on the Internet, it will send its own local network IP address within the payload of the packet, and tell the FTP server to connect to that IP address. Since this local network address is not valid outside your own network, the FTP server will not know what to do with it and hence the connection will break down. The FTP NAT helpers do all of the translations within these connections so the FTP server will actually know where to connect. The same thing applies for DCC file transfers (sends) and chats. Creating these kind of connections requires the IP address and ports to be sent within the IRC protocol, which in turn requires some translation to be done. Without these helpers, some FTP and IRC stuff will work no doubt, however, some other things will not work. For example, you may be able to receive files over DCC, but not be able to send files. This is due to how the DCC starts a connection. First off, you tell the receiver that you want to send a file and where he should connect to. Without the helpers, the DCC connection will look as if it wants the receiver to connect to some host on the receiver's own local network. In other words, the whole connection will be broken. However, the other way around, it will work flawlessly since the sender will (most probably) give you the correct address to connect to.
如果您在防火墙上遇到 mIRC DCC 问题,并且其他 IRC 客户端一切正常,请阅读常见问题和问题附录中的mIRC DCC 问题部分。 If you are experiencing problems with mIRC DCCs over your firewall and everything works properly with other IRC clients, read the mIRC DCC problems section in the Common problems and questions appendix. |
截至撰写本文时,仅可以选择加载添加对 FTP 和 IRC 协议支持的模块。有关这些 conntrack 和 nat 模块的详细说明,请阅读 常见问题和问题 附录。patch-o-matic 中还有 H.323 conntrack 帮助程序,以及其他一些 conntrack 和 NAT 帮助程序。为了能够使用这些助手,您需要使用 patch-o-matic 并编译您自己的内核。有关如何完成此操作的更好说明,请阅读“准备工作”一章。
As of this writing, there is only the option to load modules which add support for the FTP and IRC protocols. For a long explanation of these conntrack and nat modules, read the Common problems and questions appendix. There are also H.323 conntrack helpers within the patch-o-matic, as well as some other conntrack as well as NAT helpers. To be able to use these helpers, you need to use the patch-o-matic and compile your own kernel. For a better explanation on how this is done, read the Preparations chapter.
请注意,如果您希望网络地址转换在任何 FTP 和 IRC 协议上正常工作,则需要加载 ip_nat_irc 和 ip_nat_ftp。在实际加载 NAT 模块之前,您还需要加载 ip_conntrack_irc 和 ip_conntrack_ftp 模块。它们的使用方式与 conntrack 模块相同,但它将使计算机能够在这两个协议上进行 NAT。 Note that you need to load the ip_nat_irc and ip_nat_ftp if you want Network Address Translation to work properly on any of the FTP and IRC protocols. You will also need to load the ip_conntrack_irc and ip_conntrack_ftp modules before actually loading the NAT modules. They are used the same way as the conntrack modules, but it will make it possible for the computer to do NAT on these two protocols. |
此时,我们通过将 1 回显到/proc/sys/net/ipv4/ip_forward 来启动 IP 转发:
At this point we start the IP forwarding by echoing a 1 to /proc/sys/net/ipv4/ip_forward in this fashion:
回声“1”> / proc / sys / net / ipv4 / ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
我们可能值得思考一下何时何地开启 IP 转发。在此脚本和本教程中的所有其他脚本中,我们在实际创建任何类型的 IP 过滤器(即 iptables 规则集)之前将其打开。这将导致一段短暂的时间,防火墙将接受从一毫秒到一分钟之间的任何类型的流量转发,具体取决于我们正在运行的脚本和在什么机器上。这可能会给恶意者一个短暂的时间来真正穿过我们的防火墙。换句话说,这个选项确实应该在创建所有防火墙规则之后打开,但是,我选择在加载任何规则之前打开它,以保持与所有脚本中当前使用的脚本细分的一致性。 It may be worth a thought where and when we turn on the IP forwarding. In this script and all others within the tutorial, we turn it on before actually creating any kind of IP filters (i.e., iptables rule-sets). This will lead to a brief period of time where the firewall will accept forwarding of any kind of traffic for everything between a millisecond to a minute depending on what script we are running and on what box. This may give malicious people a small time-frame to actually get through our firewall. In other words, this option should really be turned on after creating all firewall rules, however, I have chosen to turn it on before loading any rules to maintain consistency with the script breakdown currently used in all scripts. |
如果您需要动态 IP 支持,例如,如果您使用 SLIP、PPP 或 DHCP,您可以通过执行以下操作来启用下一个选项 ip_dynaddr:
In case you need dynamic IP support, for example if you use SLIP, PPP or DHCP you may enable the next option, ip_dynaddr by doing the following :
回声“1”> /proc/sys/net/ipv4/ip_dynaddr
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
如果您可能需要打开任何其他选项,您应该遵循该风格。还有其他文档介绍了如何执行这些操作,但这超出了本文档的范围。有一个关于内核中可用的 proc 系统的很好但相当简短的文档,也可以在其他资源和链接附录中找到。当您要查找特定领域的信息但在此处找不到时,其他资源和链接附录通常是开始查找的好 地方。
If there is any other options you might need to turn on you should follow that style. There's other documentation on how to do these things and this is out of the scope of this documentation. There is a good but rather brief document about the proc system available within the kernel, which is also available within the Other resources and links appendix. The Other resources and links appendix is generally a good place to start looking when you have specific areas that you are looking for information on, that you do not find here.
rc.firewall.txt 脚本以及本教程中包含的所有其他脚本确实包含一小部分非必需的过程设置。当某些东西没有完全按照您想要的方式工作时,这些可能是一个很好的入门读物,但是,在真正了解这些值的含义之前,不要更改它们。 The rc.firewall.txt script, and all other scripts contained within this tutorial, do contain a small section of non-required proc settings. These may be a good primer to look at when something is not working exactly as you want it to, however, do not change these values before actually knowing what they mean. |
本节将简要描述我在教程中关于用户指定链的选择以及特定于 rc.firewall.txt脚本的一些选择。我选择走的一些路从某一方面或另一方面来说可能是错误的。我希望向您指出这些方面以及可能出现的问题的时间和地点。此外,本节还简要回顾了表和链的遍历 章节。希望这能提醒您在真实示例中如何遍历特定的表和链。
This section will briefly describe my choices within the tutorial regarding user specified chains and some choices specific to the rc.firewall.txt script. Some of the paths I have chosen to go here may be wrong from one or another aspect. I hope to point these aspects and possible problems out to you when and where they occur. Also, this section contains a brief look back to the Traversing of tables and chains chapter. Hopefully, this will remind you a little bit of how the specific tables and chains are traversed in a real live example.
我已经以尽可能节省 CPU 的方式取代了所有不同的用户链,但同时将主要重点放在安全性和可读性上。我没有让 TCP 数据包遍历 ICMP、UDP 和 TCP 规则,而是简单地匹配所有 TCP 数据包,然后让 TCP 数据包遍历用户指定的链。这样我们就不会从中获得太多开销。下图将尝试解释传入数据包如何穿越 Netfilter 的基础知识。我希望通过这些图片和解释来解释和澄清这个脚本的目标。我们暂时不会讨论任何具体细节,而是在本章中进一步讨论。与遍历表和链中的图片相比,这是一张非常微不足道的图片本章我们深入讨论了链和表的整个遍历。
I have displaced all the different user-chains in the fashion I have to save as much CPU as possible but at the same time put the main weight on security and readability. Instead of letting a TCP packet traverse ICMP, UDP and TCP rules, I simply match all TCP packets and then let the TCP packets traverse a user specified chain. This way we do not get too much overhead out of it all. The following picture will try to explain the basics of how an incoming packet traverses Netfilter. With these pictures and explanations, I wish to explain and clarify the goals of this script. We will not discuss any specific details yet, but instead further on in the chapter. This is a really trivial picture in comparison to the one in the Traversing of tables and chains chapter where we discussed the whole traversal of chains and tables in depth.
根据这张图,让我们明确我们的目标是什么。整个示例脚本基于以下假设:我们正在查看包含一个本地网络、一个防火墙和连接到防火墙的 Internet 连接的场景。此示例还基于我们拥有 Internet 静态 IP 的假设(而不是 DHCP、PPP 和 SLIP 等)。在这种情况下,我们还希望允许防火墙充当互联网上某些服务的服务器,并且我们完全信任我们的本地网络,因此我们不会阻止来自本地网络的任何流量。此外,该脚本的主要优先级是仅允许我们明确希望允许的流量。为此,我们希望将链内的默认策略设置为 DROP。
Based upon this picture, let us make clear what our goals are. This whole example script is based upon the assumption that we are looking at a scenario containing one local network, one firewall and an Internet connection connected to the firewall. This example is also based upon the assumption that we have a static IP to the Internet (as opposed to DHCP, PPP and SLIP and others). In this case, we also want to allow the firewall to act as a server for certain services on the Internet, and we trust our local network fully and hence we will not block any of the traffic from the local network. Also, this script has as a main priority to only allow traffic that we explicitly want to allow. To do this, we want to set default policies within the chains to DROP. This will effectively kill all connections and all packets that we do not explicitly allow inside our network or our firewall.
在这种情况下,我们还想让我们的本地网络连接到互联网。由于本地网络是完全可信的,因此我们希望允许从本地网络到互联网的各种流量。但是,互联网绝对不是受信任的网络,因此我们希望阻止它们访问我们的本地网络。基于这些一般假设,让我们看看我们需要做什么以及我们不需要和想要做什么。
In the case of this scenario, we would also like to let our local network do connections to the Internet. Since the local network is fully trusted, we want to allow all kinds of traffic from the local network to the Internet. However, the Internet is most definitely not a trusted network and hence we want to block them from getting to our local network. Based upon these general assumptions, let's look at what we need to do and what we do not need and want to do.
首先,我们当然希望本地网络能够连接到互联网。为此,我们需要对所有数据包进行 SNAT,因为本地计算机都没有真实的 IP 地址。所有这些都是在 POSTROUTING 链中完成的,该链是在此脚本中最后创建的。这意味着我们还必须在 FORWARD 链中进行一些过滤,否则我们将允许外部人员完全访问我们的本地网络。我们完全信任我们的本地网络,因此我们特别允许从本地网络到互联网的所有流量。由于不应允许互联网上的任何人联系我们的本地网络计算机,因此我们希望阻止从互联网到本地网络的所有流量,除了已经建立的相关连接之外,
First of all, we want the local network to be able to connect to the Internet, of course. To do this, we will need to SNAT all packets since none of the local computers have real IP addresses. All of this is done within the POSTROUTING chain, which is created last in this script. This means that we will also have to do some filtering within the FORWARD chain since we will otherwise allow outsiders full access to our local network. We trust our local network to the fullest, and because of that we specifically allow all traffic from our local network to the Internet. Since no one on the Internet should be allowed to contact our local network computers, we will want to block all traffic from the Internet to our local network except already established and related connections, which in turn will allow all return traffic from the Internet to our local network.
至于我们的防火墙,也许我们的资金有点少,或者我们只是想为互联网上的人们提供一些服务。因此,我们决定允许 HTTP、FTP、SSH 和 IDENTD 访问实际防火墙。所有这些协议在实际防火墙上都是可用的,因此应该允许它通过 INPUT 链,并且我们需要允许返回流量通过 OUTPUT 链。然而,我们也完全信任本地网络,并且环回设备和IP地址也是可信的。因此,我们希望添加特殊规则以允许来自本地网络以及环回网络接口的所有流量。此外,我们不希望允许特定的数据包或数据包标头出现在特定的连接中,也不希望允许某些 IP 范围从 Internet 到达防火墙。例如,10.0.0。0/8 地址范围是为本地网络保留的,因此我们通常不希望允许来自此地址范围的数据包,因为它们 90% 的确定性会被欺骗。但是,在实施此操作之前,我们必须注意某些互联网服务提供商实际上在自己的网络中使用这些地址范围。要对此进行更深入的讨论,请阅读常见问题和疑问章节。
As for our firewall, we may be a bit low on funds perhaps, or we just want to offer a few services to people on the Internet. Therefore, we have decided to allow HTTP, FTP, SSH and IDENTD access to the actual firewall. All of these protocols are available on the actual firewall, and hence it should be allowed through the INPUT chain, and we need to allow the return traffic through the OUTPUT chain. However, we also trust the local network fully, and the loopback device and IP address are also trusted. Because of this, we want to add special rules to allow all traffic from the local network as well as the loopback network interface. Also, we do not want to allow specific packets or packet headers in specific conjunctions, nor do we want to allow some IP ranges to reach the firewall from the Internet. For instance, the 10.0.0.0/8 address range is reserved for local networks and hence we would normally not want to allow packets from such a address range since they would with 90% certainty be spoofed. However, before we implement this, we must note that certain Internet Service Providers actually use these address ranges within their own networks. For a closer discussion of this, read the Common problems and questions chapter.
由于我们有一个在服务器上运行的 FTP 服务器,并且我们希望遍历尽可能少的规则,因此我们添加一条规则,让所有已建立的相关流量通过 INPUT 链的顶部。出于同样的原因,我们希望将规则拆分为子链。通过这样做,我们的数据包将有望只需要遍历尽可能少的规则。通过遍历更少的规则,我们可以减少每个数据包的规则集耗时,并减少网络内的延迟。
Since we have an FTP server running on the server, as well as the fact we want to traverse as few rules as possible, we add a rule which lets all established and related traffic through at the top of the INPUT chain. For the same reason, we want to split the rules down into sub-chains. By doing this, our packets will hopefully only need to traverse as few rules as possible. By traversing less rules, we make the rule-set less time-consuming for each packet, and reduce latency within the network.
在此脚本中,我们选择按协议族(例如 TCP、UDP 或 ICMP)拆分不同的数据包。所有 TCP 数据包都会遍历名为 tcp_packets 的特定链,该链将包含我们想要允许的所有 TCP 端口和协议的规则。此外,我们希望对 TCP 数据包进行一些额外的检查,因此我们希望为防火墙使用有效端口号所接受的所有数据包再创建一个子链。我们选择将此链称为允许链,并且在最终接受数据包之前应包含一些额外的检查。对于 ICMP 数据包,它们将遍历 icmp_packets 链。当我们决定如何创建这条链时,如果我们同意 ICMP 数据包的类型和代码,那么在允许 ICMP 数据包通过之前,我们看不到任何额外检查的具体需要,因此我们直接接受它们。最后,我们有需要处理的 UDP 数据包。我们将这些数据包发送到处理所有传入 UDP 数据包的 udp_packets 链。所有传入的 UDP 数据包都应发送到该链,如果它们属于允许的类型,我们应立即接受它们,而无需进行任何进一步检查。
In this script, we choose to split the different packets down by their protocol family, for example TCP, UDP or ICMP. All TCP packets traverse a specific chain named tcp_packets, which will contain rules for all TCP ports and protocols that we want to allow. Also, we want to do some extra checking on the TCP packets, so we would like to create one more subchain for all packets that are accepted for using valid port numbers to the firewall. This chain we choose to call the allowed chain, and should contain a few extra checks before finally accepting the packet. As for ICMP packets, these will traverse the icmp_packets chain. When we decided on how to create this chain, we could not see any specific needs for extra checks before allowing the ICMP packets through if we agree with the type and code of the ICMP packet, and hence we accept them directly. Finally, we have the UDP packets which need to be dealt with. These packets, we send to the udp_packets chain which handles all incoming UDP packets. All incoming UDP packets should be sent to this chain, and if they are of an allowed type we should accept them immediately without any further checking.
由于我们在一个相对较小的网络上运行,因此该设备也用作辅助工作站,并且为了为此提供一些额外的余地,我们希望允许某些特定协议与防火墙本身进行联系,例如 talk free 和 ICQ。
Since we are running on a relatively small network, this box is also used as a secondary workstation and to give some extra leeway for this, we want to allow certain specific protocols to make contact with the firewall itself, such as speak freely and ICQ.
最后,我们有防火墙的输出链。由于我们实际上非常信任防火墙,因此我们允许几乎所有流量离开防火墙。我们不会对特定用户进行任何阻止,也不会对特定协议进行任何阻止。然而,我们不希望人们使用此框来欺骗离开防火墙本身的数据包,因此我们只想允许来自分配给防火墙本身的 IP 地址的流量。我们最有可能通过添加规则来实现这一点,如果这些数据包来自分配给防火墙的 IP 地址之一,则接受所有离开防火墙的数据包,否则它们将被 OUTPUT 链中的默认策略丢弃。
Finally, we have the firewalls OUTPUT chain. Since we actually trust the firewall quite a lot, we allow pretty much all traffic leaving the firewall. We do not do any specific user blocking, nor do we do any blocking of specific protocols. However, we do not want people to use this box to spoof packets leaving the firewall itself, and hence we only want to allow traffic from the IP addresses assigned to the firewall itself. We would most likely implement this by adding rules that ACCEPT all packets leaving the firewall in case they come from one of the IP addresses assigned to the firewall, and if not they will be dropped by the default policy in the OUTPUT chain.
在创建规则集的过程中,我们很早就设置了默认策略。我们使用相当简单的命令在不同的链上设置默认策略,如下所述。
Quite early on in the process of creating our rule-set, we set up the default policies. We set up the default policies on the different chains with a fairly simple command, as described below.
iptables [-P {链} {策略}]
iptables [-P {chain} {policy}]
每次数据包与链中的规则不匹配时,都会使用默认策略。例如,假设我们收到一个数据包,该数据包与整个规则集中没有任何一条规则匹配。如果发生这种情况,我们必须决定如何处理相关数据包,这就是默认策略的用武之地。默认策略适用于与规则集中任何其他规则不匹配的所有数据包。
The default policy is used every time the packets do not match a rule in the chain. For example, let's say we get a packet that matches no single rule in our whole rule-set. If this happens, we must decide what should happen to the packet in question, and this is where the default policy comes into the picture. The default policy is used on all packets that does not match with any other rule in our rule-set.
请务必谨慎对待您在其他表中的链上设置的默认策略,因为它们根本不是为过滤而设计的,并且可能会导致非常奇怪的行为。 Do be cautious with what default policy you set on chains in other tables since they are simply not made for filtering, and it may lead to very strange behaviors. |
现在您已经清楚地了解了我们想要通过此防火墙实现的目标,所以让我们开始实际实施规则集。现在是我们负责建立我们希望创建和使用的所有规则和链以及链内的所有规则集的时候了。
Now you have a good picture of what we want to accomplish with this firewall, so let us get on to the actual implementation of the rule-set. It is now high time that we take care of setting up all the rules and chains that we wish to create and to use, as well as all of the rule-sets within the chains.
之后,我们创建要与 -N 命令一起使用的不同特殊链。新链的创建和设置内部没有任何规则。如前所述,我们将使用的链是 icmp_packets、tcp_packets、udp_packets 和 tcp_packets 链使用的 allowed 链。$INET_IFACE 上的 ICMP 类型传入数据包将被重定向到链 icmp_packets。TCP 类型的数据包将被重定向到 tcp_packets 链,来自 $INET_IFACE 的 UDP 类型的传入数据包将转到 udp_packets 链。所有这些将在下面的INPUT 链部分中进行更详细的解释。创建链非常简单,仅包含链的简短声明,如下所示:
After this, we create the different special chains that we want to use with the -N command. The new chains are created and set up with no rules inside of them. The chains we will use are, as previously described, icmp_packets, tcp_packets, udp_packets and the allowed chain, which is used by the tcp_packets chain. Incoming packets on $INET_IFACE, of ICMP type, will be redirected to the chain icmp_packets. Packets of TCP type, will be redirected to the tcp_packets chain and incoming packets of UDP type from $INET_IFACE go to udp_packets chain. All of this will be explained more in detail in the INPUT chain section below. To create a chain is quite simple and only consists of a short declaration of the chain as this:
iptables [-N链]
iptables [-N chain]
在接下来的部分中,我们将仔细研究我们现在创建的每个用户定义的链。让我们仔细看看它们的外观、它们包含哪些规则以及我们将在其中完成什么。
In the upcoming sections we will have a closer look at each of the user defined chains that we have by now created. Let us have a closer look at how they look and what rules they contain and what we will accomplish within them.
bad_tcp_packets 链专门包含检查传入数据包是否存在格式错误的标头或其他问题的规则。事实上,我们只选择包含一个数据包过滤器,它阻止所有被视为新的但没有设置 SYN 位的传入 TCP 数据包,以及阻止被视为新的 SYN/ACK 数据包的规则。该链可用于检查所有可能的不一致,例如上述或XMAS 端口扫描等。我们还可以添加查找状态 INVALID 的规则。
The bad_tcp_packets chain is devoted to contain rules that inspect incoming packets for malformed headers or other problems. As it is, we have only chosen to include a packet filter which blocks all incoming TCP packets that are considered as NEW but do not have the SYN bit set, as well as a rule that blocks SYN/ACK packets that are considered NEW. This chain could be used to check for all possible inconsistencies, such as above or XMAS port-scans etc. We could also add rules that looks for state INVALID.
如果您想完全理解 NEW 而不是 SYN,则需要查看 常见问题和问题附录中 有关状态 NEW 和非 SYN 数据包通过其他规则的状态 NEW 数据包但没有 SYN 位设置部分。在某些情况下可以允许这些数据包,但在 99% 的情况下,我们不希望这些数据包通过。因此,我们将它们记录到我们的日志中,然后删除它们。
If you want to fully understand the NEW not SYN, you need to look at the State NEW packets but no SYN bit set section in the Common problems and questions appendix regarding state NEW and non-SYN packets getting through other rules. These packets could be allowed under certain circumstances but in 99% of the cases we wouldn't want these packets to get through. Hence, we log them to our logs and then we DROP them.
我们拒绝被认为是 NEW 的 SYN/ACK 数据包的原因也很简单。常见问题和疑问附录中的SYN/ACK 和 NEW 数据包部分对此进行了更深入的描述。基本上,我们这样做是出于对其他主机的礼貌,因为我们将防止它们在序列号预测攻击中受到攻击。
The reason that we REJECT SYN/ACK packets that are considered NEW is also very simple. It is described in more depth in the SYN/ACK and NEW packets section in the Common problems and questions appendix. Basically, we do this out of courtesy to other hosts, since we will prevent them from being attacked in a sequence number prediction attack.
如果数据包进入 $INET_IFACE 并且是 TCP 类型,它会通过 tcp_packets 链传输,并且如果该连接是针对我们希望允许流量通过的端口,我们需要对其进行一些最终检查,看看我们是否真的是否愿意允许。所有这些最终检查都是在允许的链内完成的。
If a packet comes in on $INET_IFACE and is of TCP type, it travels through the tcp_packets chain and if the connection is against a port that we want to allow traffic on, we want to do some final checks on it to see if we actually do want to allow it or not. All of these final checks are done within the allowed chain.
首先,我们检查数据包是否是SYN数据包。如果它是 SYN 数据包,则它很可能是新连接中的第一个数据包,因此我们当然允许这样做。然后我们检查数据包是否来自 ESTABLISHED 或 RELATED 连接,如果是,那么我们当然再次允许它。ESTABLISHED 连接是已经看到双向流量的连接,并且由于我们已经看到 SYN 数据包,因此根据状态机,该连接必须处于 ESTABLISHED 状态。该链中的最后一条规则将删除其他所有规则。在这种情况下,这几乎意味着没有看到双向流量的所有情况,即我们没有回复 SYN 数据包,或者他们正在尝试使用非 SYN 数据包启动连接。没有_不使用 SYN 数据包启动连接的实际用途,除了端口扫描之外。据我所知,当前没有可用的 TCP/IP 实现支持使用 SYN 数据包以外的其他内容打开 TCP 连接,因此,将其丢弃,因为它 99% 肯定是端口扫描。
First of all, we check if the packet is a SYN packet. If it is a SYN packet, it is most likely to be the first packet in a new connection so, of course, we allow this. Then we check if the packet comes from an ESTABLISHED or RELATED connection, if it does, then we, again of course, allow it. An ESTABLISHED connection is a connection that has seen traffic in both directions, and since we have seen a SYN packet, the connection then must be in state ESTABLISHED, according to the state machine. The last rule in this chain will DROP everything else. In this case this pretty much means everything that has not seen traffic in both directions, i.e., we didn't reply to the SYN packet, or they are trying to start the connection with a non SYN packet. There is no practical use of not starting a connection with a SYN packet, except to port scan people pretty much. There is no currently available TCP/IP implementation that supports opening a TCP connection with something else than a SYN packet to my knowledge, hence, DROP it since it is 99% sure to be a port scan.
关于 ESTABLISHED,RELATED 数据包的规则实际上在此脚本中是多余的,不会被使用,但为了完整起见已包含在内。将使用的规则放置在 INPUT 链的顶部,并且还包含 ESTABLISHED、RELATED。 The rule regarding ESTABLISHED,RELATED packets is actually redundant in this script and will not be used, but has been included for the sake of being complete. The rule that will be used is placed at the top of the INPUT chain, and contains ESTABLISHED,RELATED as well. |
tcp_packets 链指定防火墙上允许使用来自 Internet 的端口。然而,还有更多的检查要做,因此我们将每个数据包发送到允许的链上,正如我们之前描述的那样。
The tcp_packets chain specifies what ports are allowed to use on the firewall from the Internet. There is, however, even more checks to do, hence we send each and every one of the packets on to the allowed chain, which we described previously.
-A tcp_packets 告诉 iptables 在哪个链中添加新规则,该规则将被添加到链的末尾。-p TCP 告诉它匹配 TCP 数据包,而 -s 0/0 匹配从 0.0.0.0 到网络掩码 0.0.0.0 的所有源地址,换句话说,所有源地址。这实际上是默认行为,但我使用它只是为了使一切尽可能清晰。--dport 21 表示目标端口 21,换句话说,如果数据包发往端口 21,它们也会匹配。如果所有条件都匹配,则数据包将定位到允许的链。如果它不匹配任何规则,它们将被传递回将数据包发送到 tcp_packets 链的原始链。
-A tcp_packets tells iptables in which chain to add the new rule, the rule will be added to the end of the chain. -p TCP tells it to match TCP packets and -s 0/0 matches all source addresses from 0.0.0.0 with netmask 0.0.0.0, in other words all source addresses. This is actually the default behavior but I am using it just to make everything as clear as possible. --dport 21 means destination port 21, in other words if the packet is destined for port 21 they also match. If all the criteria are matched, then the packet will be targeted for the allowed chain. If it doesn't match any of the rules, they will be passed back to the original chain that sent the packet to the tcp_packets chain.
现在,我允许 TCP 端口 21 或 FTP 控制端口,用于控制 FTP 连接,稍后我还允许所有相关连接,这样我们就允许被动和主动连接,因为 ip_conntrack_ftp 模块希望是,已加载。如果我们根本不想允许 FTP,我们可以卸载 ip_conntrack_ftp 模块并从rc.firewall.txt文件中删除 $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed 行。
As it is now, I allow TCP port 21, or FTP control port, which is used to control FTP connections and later on I also allow all RELATED connections, and that way we allow PASSIVE and ACTIVE connections since the ip_conntrack_ftp module is, hopefully, loaded. If we do not want to allow FTP at all, we can unload the ip_conntrack_ftp module and delete the $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed line from the rc.firewall.txt file.
端口 22 是 SSH,如果您想允许外部任何人在您的机器上使用 shell,这比在端口 23 上允许 telnet 好得多。请注意,您正在处理防火墙。给除了你自己之外的其他人任何形式的防火墙访问权限总是一个坏主意。防火墙应始终保持在最低限度,仅此而已。
Port 22 is SSH, which is much better than allowing telnet on port 23 if you want to allow anyone from the outside to use a shell on your box at all. Note that you are dealing with a firewall. It is always a bad idea to give others than yourself any kind of access to a firewall box. Firewalls should always be kept to a bare minimum and no more.
端口 80 是 HTTP,换句话说,您的 Web 服务器,如果您不想直接在防火墙上运行 Web 服务器,请将其删除。
Port 80 is HTTP, in other words your web server, delete it if you do not want to run a web server directly on your firewall.
最后,我们允许端口 113,这是 IDENTD,对于 IRC 等某些协议的正常工作可能是必需的。请注意,如果您对本地网络上的多个主机进行 NAT,那么使用 oidentd 包可能是值得的。oidentd 支持将 IDENTD 请求中继到本地网络中的正确盒子。
And finally we allow port 113, which is IDENTD and might be necessary for some protocols like IRC, etc to work properly. Do note that it may be worth it to use the oidentd package if you NAT several hosts on your local network. oidentd has support for relaying IDENTD requests on to the correct boxes within your local network.
如果您想使用此脚本添加更多开放端口,那么现在应该很明显如何做到这一点。只需剪切并粘贴 tcp_packets 链中的其他行之一,并将其更改为您要打开的端口。
If you feel like adding more open ports with this script, well, it should be quite obvious how to do that by now. Just cut and paste one of the other lines in the tcp_packets chain and change it to the port you want to open.
如果我们确实在 INPUT 链上收到了 UDP 数据包,我们会将它们发送到 udp_packets,在那里我们再次使用 -p UDP 对 UDP 协议进行匹配,然后将所有内容与源地址 0.0.0.0 和网络掩码 0.0.0.0 进行匹配,换句话说,一切又来了。除了这一次,我们只接受我们希望为 Internet 上的主机开放的特定 UDP 端口。请注意,我们不需要根据发送主机的源端口打开漏洞,因为这应该由状态机处理。如果我们要在任何 UDP 端口(例如 DNS 等)上运行服务器,我们只需要在主机上打开端口。进入防火墙并且属于已建立连接(通过我们的本地网络)的一部分的数据包将自动被 INPUT 链顶部的 --state ESTABLISHED,RELATED 规则接受。
If we do get a UDP packet on the INPUT chain, we send them on to udp_packets where we once again do a match for the UDP protocol with -p UDP and then match everything with a source address of 0.0.0.0 and netmask 0.0.0.0, in other words everything again. Except this time, we only accept specific UDP ports that we want to be open for hosts on the Internet. Do note that we do not need to open up holes depending on the sending hosts source port, since this should be taken care of by the state machine. We only need to open up ports on our host if we are to run a server on any UDP port, such as DNS etc. Packets that are entering the firewall and that are part of an already established connection (by our local network) will automatically be accepted back in by the --state ESTABLISHED,RELATED rules at the top of the INPUT chain.
事实上,我们不接受来自端口 53 的传入 UDP 数据包,这是我们用来进行 DNS 查找的端口。规则就在那里,但默认情况下已被注释掉。如果您希望防火墙充当 DNS 服务器,请取消注释此行。
As it is, we do not ACCEPT incoming UDP packets from port 53, which is what we use to do DNS lookups. The rule is there, but it is per default commented out. If you want your firewall to act as a DNS server, uncomment this line.
我个人还允许端口 123,这是 NTP 或网络时间协议。该协议用于将您的计算机时钟设置为与某些具有 非常准确的时钟的其他时间服务器相同的时间。你们中的大多数人可能不使用这个协议,因此我默认不允许它。同样的事情也适用于此,但是,规则就在那里,并且很容易取消注释即可使其正常工作。
I personally also allow port 123, which is NTP or network time protocol. This protocol is used to set your computer clock to the same time as certain other time servers which have very accurate clocks. Most of you probably do not use this protocol and hence I am not allowing it per default. The same thing applies here, however, the rule is there and it is simple to uncomment to get it working.
我们目前不允许端口 2074,该端口用于某些实时 多媒体应用程序,例如自由发言,您可以使用扬声器和麦克风(甚至更好的是耳机)与其他人实时交谈。如果您想使用此功能,只需删除注释即可将其打开。
We do not currently allow port 2074, which is used for certain real-time multimedia applications like speak freely which you can use to talk to other people in real-time by using speakers and a microphone, or even better, a headset. If you would like to use this, you could turn it on quite simply by removing the comment.
端口 4000 是 ICQ 协议。这应该是一个非常知名的协议,由名为 ICQ 的 Mirabilis 应用程序使用。Linux 上至少有 2-3 个不同的 ICQ 克隆版本,它是世界上使用最广泛的聊天程序之一。我怀疑是否有必要进一步解释它是什么。
Port 4000 is the ICQ protocol. This should be an extremely well known protocol that is used by the Mirabilis application named ICQ. There are at least 2-3 different ICQ clones for Linux and it is one of the most widely used chat programs in the world. I doubt there is any further need to explain what it is.
此时,如果您由于不同情况而遇到大量日志条目,则可以使用两个额外的规则。第一条规则将阻止到目标端口 135 到 139 的广播数据包。这些由 NetBIOS 或大多数 Microsoft 用户的 SMB 使用。这将阻止我们可能从防火墙外部记录 Microsoft 网络活动的 iptables 获取的所有日志条目。第二条规则也是为了解决过多的日志记录问题而创建的,但它负责处理来自外部的 DHCP 查询。如果您的外部网络由非交换以太网类型的网络组成,其中客户端通过 DHCP 接收其 IP 地址,则尤其如此。在这些情况下,您可能会因此获得大量日志。
At this point, two extra rules are available if you are experiencing a lot of log entries due to different circumstances. The first rule will block broadcast packets to destination ports 135 through 139. These are used by NetBIOS, or SMB for most Microsoft users. This will block all log entries we may get from iptables logging Microsoft network activity on the outside of our firewall. The second rule was also created to take care of excessive logging problems, but instead takes care of DHCP queries from the outside. This is specifically true if your outside network consists of a non-switched Ethernet type of network, where the clients receive their IP addresses by DHCP. During these circumstances, you could wind up with a lot of logs from just that.
请注意,最后两条规则是专门选择退出的,因为有些人可能对此类日志感兴趣。如果您遇到过多合法日志记录的问题,请尝试此时删除这些类型的包。在 INPUT 链中的日志规则之前还有更多此类规则。 Do note that the last two rules are specifically opted out since some people may be interested in these kind of logs. If you are experiencing problems with excessive legit logging, try to drop these types of packages at this point. There are also more rules of this type just before the log rules in the INPUT chain. |
这是我们决定允许哪些 ICMP 类型的地方。如果 ICMP 类型的数据包进入 INPUT 链上的 eth0,我们会将其重定向到 icmp_packets 链,如前所述。在这里我们检查允许哪些类型的 ICMP 类型。目前,我只允许传入 ICMP Echo 请求,在传输期间 TTL 等于 0,在重组期间 TTL 等于 0。我们此处默认不允许任何其他 ICMP 类型的原因是,几乎所有其他 ICMP 类型都应包含在 RELATED 状态规则中。
This is where we decide what ICMP types to allow. If a packet of ICMP type comes in on eth0 on the INPUT chain, we then redirect it to the icmp_packets chain as explained before. Here we check what kind of ICMP types to allow. For now, I only allow incoming ICMP Echo requests, TTL equals 0 during transit and TTL equals 0 during reassembly. The reason that we do not allow any other ICMP types per default here, is that almost all other ICMP types should be covered by the RELATED state rules.
如果 ICMP 数据包作为对已存在数据包或数据包流的回复而发送,则它被视为与原始流相关。有关状态的更多信息,请阅读状态机章节。 If an ICMP packet is sent as a reply to an already existing packet or packet stream it is considered RELATED to the original stream. For more information on the states, read the The state machine chapter. |
我允许这些 ICMP 数据包的原因如下,回显请求用于请求回显答复,而回显答复主要用于 ping 其他主机以查看它们是否在任何网络上可用。如果没有此规则,其他主机将无法对我们进行 ping 操作以查看我们是否可以在任何网络连接上使用。请注意,有些人倾向于删除这条规则,因为他们只是不想在互联网上被看到。删除此规则将有效地使来自 Internet 的对我们防火墙的任何 ping 完全无用,因为防火墙根本不会响应它们。
The reason that I allow these ICMP packets is as follows, Echo Requests are used to request an echo reply, which in turn is used to mainly ping other hosts to see if they are available on any of the networks. Without this rule, other hosts will not be able to ping us to see if we are available on any network connection. Do note that some people would tend to erase this rule, since they simply do not want to be seen on the Internet. Deleting this rule will effectively render any pings to our firewall totally useless from the Internet since the firewall will simply not respond to them.
时间超出(即,传输期间 TTL 等于 0,重组期间 TTL 等于 0),在我们想要跟踪路由某个主机的情况下是允许的,或者如果数据包的生存时间设置为 0,我们将收到有关的回复这。例如,当您对某人进行跟踪路由时,您从 TTL = 1 开始,在出去的第一跳处降至 0,并且从第一个网关发送回我们发送给我们的主机的超时时间。正在尝试跟踪路由,然后 TTL = 2,第二个网关发送“超时”消息,依此类推,直到我们从最终想要到达的主机收到实际答复。这样,我们将在到达我们想要到达的实际主机的途中得到每个主机的回复,并且我们可以看到中间的每个主机并找出哪个主机损坏了。
Time Exceeded (i.e., TTL equals 0 during transit and TTL equals 0 during reassembly), is allowed in the case we want to trace-route some host or if a packet gets its Time To Live set to 0, we will get a reply about this. For example, when you trace-route someone, you start out with TTL = 1, and it gets down to 0 at the first hop on the way out, and a Time Exceeded is sent back from the first gateway en route to the host we are trying to trace-route, then TTL = 2 and the second gateway sends Time Exceeded, and so on until we get an actual reply from the host we finally want to get to. This way, we will get a reply from each host on our way to the actual host we want to reach, and we can see every host in between and find out what host is broken.
有关所有 ICMP 类型的完整列表,请参阅 ICMP 类型附录。有关 ICMP 类型及其用法的更多信息,我建议阅读以下文档和报告:
For a complete listing of all ICMP types, see the ICMP types appendix . For more information on ICMP types and their usage, i suggest reading the following documents and reports:
RFC 792 - J. Postel 的互联网控制消息协议。
RFC 792 - Internet Control Message Protocol by J. Postel.
顺便说一句,我为您阻止其中一些 ICMP 类型可能是错误的,但就我而言,在阻止我不允许的所有 ICMP 类型的同时,一切都运行良好。 As a side-note, I might be wrong in blocking some of these ICMP types for you, but in my case, everything works perfectly while blocking all the ICMP types that I do not allow. |
正如我所写的,INPUT 链主要使用其他链来完成艰苦的工作。这样我们就不会从 iptables 获得太多负载,并且它在慢速机器上会工作得更好,否则可能会在高负载时丢包。这是通过检查许多不同数据包应该相同的特定细节,然后将这些数据包发送到特定的用户指定的链来完成的。通过这样做,我们可以拆分规则集,以包含每个数据包需要遍历的更少的规则,因此防火墙通过数据包过滤所承受的开销会少得多。
The INPUT chain, as I have written it, uses mostly other chains to do the hard work. This way we do not get too much load from iptables, and it will work much better on slow machines which might otherwise drop packets at high loads. This is done by checking for specific details that should be the same for a lot of different packets, and then sending those packets into specific user specified chains. By doing this, we can split down our rule-set to contain much less rules that need to be traversed by each packet and hence the firewall will be put through a lot less overhead by packet filtering.
首先,我们对坏数据包进行某些检查。这是通过将所有 TCP 数据包发送到 bad_tcp_packets 链来完成的。该链包含一些规则,用于检查格式错误的数据包或我们不想接受的其他异常情况。有关 bad_tcp_packets 链的完整说明,请查看 本章的 bad_tcp_packets 链部分。
First of all we do certain checks for bad packets. This is done by sending all TCP packets to the bad_tcp_packets chain. This chain contains a few rules that will check for badly formed packets or other anomalies that we do not want to accept. For a full explanation of the bad_tcp_packets chain, take a look in the The bad_tcp_packets chain section in this chapter.
此时,我们开始寻找来自普遍可信网络的流量。这些包括本地网络适配器和来自那里的所有流量,进出我们的环回接口的所有流量,包括我们当前分配的所有 IP 地址(这意味着所有这些,包括我们的 Internet IP 地址)。事实上,我们选择将允许 LAN 活动发送到防火墙的规则放在顶部,因为我们的本地网络产生的流量比 Internet 连接多。这样可以减少用于尝试将每个数据包与每个规则进行匹配的开销,并且查看主要穿越防火墙的流量类型始终是一个好主意。通过这样做,我们可以调整规则以提高效率,从而减少防火墙的开销和网络的拥塞。
At this point we start looking for traffic from generally trusted networks. These include the local network adapter and all traffic coming from there, all traffic to and from our loopback interface, including all our currently assigned IP addresses (this means all of them, including our Internet IP address). As it is, we have chosen to put the rule that allows LAN activity to the firewall at the top, since our local network generates more traffic than the Internet connection. This allows for less overhead used to try and match each packet with each rule and it is always a good idea to look through what kind of traffic mostly traverses the firewall. By doing this, we can shuffle around the rules to be more efficient, leading to less overhead on the firewall and less congestion on your network.
在我们开始接触“真正的”规则(这些规则决定我们允许哪些内容不允许通过互联网接口)之前,我们设置了一个相关的规则来减少我们的开销。这是一条状态规则,允许已 ESTABLISHED 或 RELATED 流的所有数据包部分发送到 Internet IP 地址。该规则在允许的链中有一个等效的规则,该规则使该规则变得相当冗余,它将在允许的规则之前进行评估。然而,由于多种原因,允许链中的 --state ESTABLISHED,RELATED 规则被保留,例如人们想要剪切和粘贴该功能。
Before we start touching the "real" rules which decide what we allow from the Internet interface and not, we have a related rule set up to reduce our overhead. This is a state rule which allows all packets part of an already ESTABLISHED or RELATED stream to the Internet IP address. This rule has an equivalent rule in the allowed chain, which are made rather redundant by this rule, which will be evaluated before the allowed ones are. However, the --state ESTABLISHED,RELATED rule in the allowed chain has been retained for several reasons, such as people wanting to cut and paste the function.
之后,我们匹配来自 $INET_IFACE 接口的 INPUT 链中的所有 TCP 数据包,并将这些数据包发送到 tcp_packets,这在前面已经描述过。现在我们对 $INET_IFACE 上的 UDP 数据包进行相同的匹配,并将它们发送到 udp_packets 链,之后所有 ICMP 数据包都发送到 icmp_packets 链。通常,防火墙最容易受到 TCP 数据包的攻击,其次是 UDP,最后是 ICMP 数据包。请注意,这是正常情况,但对您来说可能是错误的。这里应该考虑完全相同的事情,就像网络特定的规则一样。哪一个造成的流量最多?是否应该抛弃这些规则以减少开销?在发送大量数据的网络上,这是绝对必要的,因为如果规则集编写得不好,包含 100 条规则的简单规则集和满负荷运行的单个 100mbit 以太网卡可能会让 Pentium III 等效机器崩溃。在为您自己的本地网络编写规则集时,这是需要考虑的重要部分。
After this, we match all TCP packets in the INPUT chain that comes in on the $INET_IFACE interface, and send those to the tcp_packets, which was previously described. Now we do the same match for UDP packets on the $INET_IFACE and send those to the udp_packets chain, and after this all ICMP packets are sent to the icmp_packets chain. Normally, a firewall would be hardest hit by TCP packets, than UDP and last of them all ICMP packets. This is in normal case, mind you, and it may be wrong for you. The absolute same thing should be looked upon here, as with the network specific rules. Which causes the most traffic? Should the rules be thrown around to generate less overhead? On networks sending huge amounts of data, this is an absolute necessity since a Pentium III equivalent machine may be brought to its knees by a simple rule-set containing 100 rules and a single 100mbit Ethernet card running at full capacity if the rule-set is badly written. This is an important piece to look at when writing a rule-set for your own local network.
此时,我们有一个额外的规则,即默认选择退出的规则,可用于消除一些过多的日志记录,以防我们的 Linux 防火墙外部有一些 Microsoft 网络。Microsoft 客户端有向 224.0.0.0/8 范围发送大量多播数据包的坏习惯,因此我们有机会在这里阻止这些数据包,这样我们就不会用它们填充日志。还有另外两个规则执行与UDP 链中描述的 udp_packets 链中的任务类似的任务。
At this point we have one extra rule, that is per default opted out, that can be used to get rid of some excessive logging in case we have some Microsoft network on the outside of our Linux firewall. Microsoft clients have a bad habit of sending out tons of multicast packets to the 224.0.0.0/8 range, and hence we have the opportunity to block those packets here so we don't fill our logs with them. There are also two more rules doing something similar to tasks in the udp_packets chain described in the The UDP chain.
在我们使用 INPUT 链的默认策略之前,我们会将其记录下来,以便我们能够找出可能的问题和/或错误。它可能是我们不想允许的数据包,也可能是有人对我们做了坏事,或者最后可能是我们的防火墙出现问题,不允许应该允许的流量。无论哪种情况,我们都想了解它,以便可以对其进行处理。不过,我们每分钟记录的数据包不会超过 3 个,因为我们不想用垃圾淹没我们的日志,这反过来可能会填满我们的整个日志分区,我们还为所有日志条目设置了一个前缀,以便我们知道它来自哪里。
Before we hit the default policy of the INPUT chain, we log it so we may be able to find out about possible problems and/or bugs. Either it might be a packet that we just do not want to allow or it might be someone who is doing something bad to us, or finally it might be a problem in our firewall not allowing traffic that should be allowed. In either case we want to know about it so it can be dealt with. Though, we do not log more than 3 packets per minute as we do not want to flood our logs with crap which in turn may fill up our whole logging partition, also we set a prefix to all log entries so we know where it came from.
所有尚未捕获的内容都将被 INPUT 链上的默认策略删除。默认策略是很久以前就设置的,在本章的 设置默认策略部分。
Everything that has not yet been caught will be DROPed by the default policy on the INPUT chain. The default policy was set quite some time back, in the Setting up default policies section, in this chapter.
在这种情况下,FORWARD 链包含相当多的规则。我们有一个规则,它将所有数据包发送到 bad_tcp_packets 链,该规则也用于前面描述的 INPUT 链中。bad_tcp_packets 链的构造方式使得它可以在多个调用链中循环使用,无论什么数据包穿过它。
The FORWARD chain contains quite a few rules in this scenario. We have a single rule which sends all packets to the bad_tcp_packets chain, which was also used in the INPUT chain as described previously. The bad_tcp_packets chain is constructed in such a fashion that it can be used recycled in several calling chains, regardless of what packet traverses it.
在第一次检查坏的 TCP 数据包之后,我们就得到了 FORWARD 链中的主要规则。第一条规则将允许从 $LAN_IFACE 到任何其他接口的所有流量自由流动,不受限制。换句话说,该规则将允许从我们的 LAN 到 Internet 的所有流量。第二条规则将允许 ESTABLISHED 和 RELATED 流量通过防火墙返回。换句话说,这将允许属于从我们的内部网络发起的连接的数据包自由流回我们的本地网络。这些规则是我们的本地网络能够访问互联网所必需的,因为 FORWARD 链的默认策略之前设置为 DROP。这非常聪明,因为它将允许我们本地网络上的主机连接到互联网上的主机,
After this first check for bad TCP packets, we have the main rules in the FORWARD chain. The first rule will allow all traffic from our $LAN_IFACE to any other interface to flow freely, without restrictions. This rule will in other words allow all traffic from our LAN to the Internet. The second rule will allow ESTABLISHED and RELATED traffic back through the firewall. This will in other words allow packets belonging to connections that were initiated from our internal network to flow freely back to our local network. These rules are required for our local network to be able to access the Internet, since the default policy of the FORWARD chain was previously set to DROP. This is quite clever, since it will allow hosts on our local network to connect to hosts on the Internet, but at the same time block hosts on the Internet from connecting to the hosts on our internal network.
最后,我们还有一个日志记录规则,它将记录不允许以一种或另一种方式通过 FORWARD 链的数据包。这很可能表明出现了一个或另一个格式错误的数据包或其他问题。原因之一可能是黑客攻击,其他原因可能是数据包格式错误。除了日志前缀“IPT FORWARD packet dead:”之外,这与 INPUT 链中使用的规则完全相同。日志前缀主要用于分隔日志条目,并且可以用于区分日志条目以找出数据包是从哪里记录的以及一些标头选项。
Finally we also have a logging rule which will log packets that are not allowed in one or another way to pass through the FORWARD chain. This will most likely show one or another occurrence of a badly formed packet or other problem. One cause may be hacker attacks, and others may be malformed packets. This is exactly the same rule as the one used in the INPUT chain except for the logging prefix, "IPT FORWARD packet died: ". The logging prefix is mainly used to separate log entries, and may be used to distinguish log entries to find out where the packet was logged from and some header options.
因为我知道除了我之外几乎没有人使用这个盒子,它目前部分用作防火墙和工作站,所以我允许几乎所有从它发出的具有源地址 $LOCALHOST_IP、$LAN_IP 或 $STATIC_IP 的内容。其他一切都可能以某种方式被欺骗,尽管我怀疑我认识的人会在我的盒子上这样做。最后,我们记录所有被丢弃的东西。如果它确实被删除,我们肯定会想知道它,以便我们可以采取行动解决这个问题。要么是一个严重的错误,要么是一个被欺骗的奇怪数据包。最后我们按照默认策略丢弃数据包。
Since I know that there is pretty much no one but me using this box which is partially used as a Firewall and a workstation currently, I allow almost everything that goes out from it that has a source address $LOCALHOST_IP, $LAN_IP or $STATIC_IP. Everything else might be spoofed in some fashion, even though I doubt anyone that I know would do it on my box. Last of all we log everything that gets dropped. If it does get dropped, we will most definitely want to know about it so we may take action against the problem. Either it is a nasty error, or it is a weird packet that is spoofed. Finally we DROP the packet in the default policy.
PREROUTING 链正如其所言,它在数据包实际达到将数据包发送到过滤器表中的 INPUT 或 FORWARD 链的路由决策之前对其进行网络地址转换。我们在此脚本中讨论此链的唯一原因是我们有必要再次指出您不应在其中进行任何过滤。PREROUTING 链仅由流中的第一个数据包遍历,这意味着该链中的所有后续数据包将完全不受检查。与此脚本一样,我们根本不使用 PREROUTING 链,但是,如果我们想对任何特定数据包进行 DNAT(例如,如果您想托管您的网络),这就是我们现在要工作的地方您本地网络中的服务器。有关 PREROUTING 链的更多信息,请阅读表和链的遍历章节。
The PREROUTING chain is pretty much what it says, it does network address translation on packets before they actually hit the routing decision that sends them onward to the INPUT or FORWARD chains in the filter table. The only reason that we talk about this chain in this script is that we once again feel obliged to point out that you should not do any filtering in it. The PREROUTING chain is only traversed by the first packet in a stream, which means that all subsequent packets will go totally unchecked in this chain. As it is with this script, we do not use the PREROUTING chain at all, however, this is the place we would be working in right now if we wanted to do DNAT on any specific packets, for example if you want to host your web server within your local network. For more information about the PREROUTING chain, read the Traversing of tables and chains chapter.
PREROUTING 链不应该用于任何过滤,因为除其他外,该链仅由流中的第一个数据包遍历。PREROUTING 链应该仅用于网络地址转换,除非您真的知道自己在做什么。 The PREROUTING chain should not be used for any filtering since, among other things, this chain is only traversed by the first packet in a stream. The PREROUTING chain should be used for network address translation only, unless you really know what you are doing. |
那么,我们的最终任务是启动网络地址转换,对吗?至少对我来说。首先,我们在 POSTROUTING 链中的 nat 表中添加一条规则,该规则将对从我们连接到 Internet 的接口发出的所有数据包进行 NAT。对我来说这就是 eth0。但是,所有示例脚本中都添加了特定变量,可用于自动配置这些设置。-t 选项告诉 iptables 将规则插入到哪个表中,在本例中是 nat 表。-A 命令告诉我们要向名为 POSTROUTING 的现有链追加一条新规则,而 -o $INET_IFACE 告诉我们匹配 INET_IFACE 接口(或 eth0,根据此脚本中的默认设置)上的所有传出数据包,最后我们将目标设置为对数据包进行 SNAT。因此,所有与此规则匹配的数据包都将被 SNAT 处理,看起来就像来自您的 Internet 接口。请注意,您必须使用 --to-source 选项设置发送到 SNAT 目标的传出数据包的 IP 地址。
So, our final mission would be to get the Network Address Translation up, correct? At least to me. First of all we add a rule to the nat table, in the POSTROUTING chain that will NAT all packets going out on our interface connected to the Internet. For me this would be eth0. However, there are specific variables added to all of the example scripts that may be used to automatically configure these settings. The -t option tells iptables which table to insert the rule in, in this case the nat table. The -A command tells us that we want to Append a new rule to an existing chain named POSTROUTING and -o $INET_IFACE tells us to match all outgoing packets on the INET_IFACE interface (or eth0, per default settings in this script) and finally we set the target to SNAT the packets. So all packets that match this rule will be SNAT'ed to look as if they came from your Internet interface. Do note that you must set which IP address to give outgoing packets with the --to-source option sent to the SNAT target.
在此脚本中,出于几个原因,我们选择使用 SNAT 目标而不是 MASQUERADE。第一个是该脚本应该在具有静态 IP 地址的防火墙上运行。因此,第一个原因的后续原因是,如果可能的话,使用 SNAT 目标会更快、更有效。当然,它也被用来展示它是如何工作的以及如何在真实的例子中使用它。如果您没有静态 IP 地址,您绝对应该考虑使用 MASQUERADE 目标,它提供了一个简单易用的工具,也可以为您执行 NAT,但会自动获取它应该使用的 IP 地址。这需要一点额外的计算能力,但如果您使用 DHCP 的话,这绝对是值得的。 rc.DHCP.firewall.txt脚本。
In this script we have chosen to use the SNAT target instead of MASQUERADE for a couple of reasons. The first one is that this script was supposed to run on a firewall that has a static IP address. A follow up reason to the first one, would hence be that it is faster and more efficient to use the SNAT target if possible. Of course, it was also used to show how it would work and how it would be used in a real live example. If you do not have a static IP address, you should definitely give thought to use the MASQUERADE target instead which provides a simple and easy facility that will also do NAT for you, but that will automatically grab the IP address that it should use. This takes a little bit extra computing power, but it may most definitely be worth it if you use DHCP for instance. If you would like to have a closer look at how the MASQUERADE target may look, you should look at the rc.DHCP.firewall.txt script.
本章解释了不同脚本的一些布局,特别是rc.firewall.txt脚本。这里描述的脚本的布局和内部工作原理与其他地方的脚本可能有很大的不同。每个人都有自己的编码风格,我们编写规则集、代码或脚本的方式因人而异,您在这里看到的风格就是我的风格。
This chapter has explained some of the layout of the different scripts, but specifically the rc.firewall.txt script. The layout and inner workings of scripts described here and those found in other places can differ tremenduously. Everyone has their own coding style and how we write rulesets or code or scripts differ from person to person, and the style you've seen here is my style.
下一章将简要介绍本文档中可用的不同脚本。他们会给你一些基本的想法,这些脚本是为什么场景编写的,然后你应该有足够的自学能力,能够自己掌握脚本的其余部分。所有这些脚本也可以在本文档的主站点上下载。
The next chapter will give some brief introductions to the different scripts available within this document. They will give you some basic idea what scenarios the scripts where written for, and then you should hopefully have taught yourself enough to grasp the rest of the scripts on your own. All of these scripts are also available for download on the main site of this document.
本章的目的是对本教程中提供的每个脚本进行相当简短的解释,并提供脚本及其提供的服务的概述。这些脚本无论如何都不是完美的,它们可能并不完全符合您的确切意图。换句话说,您可以根据自己的需要来制作这些脚本。本教程的其余部分很可能有助于实现这一壮举。本教程的第一部分涉及我在每个脚本中建立的实际结构,因此我们可以更轻松地在脚本中找到我们的方法。
The objective of this chapter is to give a fairly brief and short explanation of each script available with this tutorial, and to provide an overview of the scripts and what services they provide. These scripts are not in any way perfect, and they may not fit your exact intentions perfectly. It is, in other words, up to you to make these scripts suitable for your needs. The rest of this tutorial should most probably be helpful in making this feat. The first section of this tutorial deals with the actual structure that I have established in each script so we may find our way within the script a bit easier.
本教程编写的所有脚本都是按照特定结构编写的。这样做的原因是它们应该彼此相当相似,并且更容易找到脚本之间的差异。这个结构应该在这个简短的章节中得到很好的记录。希望本章能够让您简要了解为什么所有脚本都是这样编写的,以及为什么我选择维持这种结构。
All scripts written for this tutorial have been written after a specific structure. The reason for this is that they should be fairly similar to each other and to make it easier to find the differences between the scripts. This structure should be fairly well documented in this brief chapter. This chapter should hopefully give a short understanding to why all the scripts have been written as they have, and why I have chosen to maintain this structure.
尽管这是我选择的结构,但请注意,这可能不是最适合您的脚本的结构。这只是我选择使用的一种结构,因为它符合易于阅读的需要,并根据我的逻辑遵循最好的结构。 Even though this is the structure I have chosen, do note that this may not be the best structure for your scripts. It is only a structure that I have chosen to use since it fits the need of being easy to read and follow the best according to my logic. |
这是本教程中的所有脚本都应遵循的结构。如果它们在某些方面有所不同,则可能是我的错误,除非特别解释了为什么我破坏了这个结构。
This is the structure that all scripts in this tutorial should follow. If they differ in some way it is probably an error on my part, unless it is specifically explained why I have broken this structure.
配置- 首先,我们有脚本其余部分应使用的配置选项。配置选项几乎应该始终是任何 shell 脚本中的第一件事。
互联网- 这是与互联网连接有关的配置部分。如果我们没有任何互联网连接,则可以跳过此步骤。请注意,可能还有比此处列出的更多的小节,但仅限于与我们的互联网连接有关的小节。
DHCP - 如果此特定脚本可能有任何特殊 DHCP 要求,我们将在此处添加 DHCP 特定配置选项。
PPPoE - 如果用户有可能想要使用此特定脚本,并且有任何特殊情况增加了他使用 PPPoE 连接的可能性,我们将在此处添加特定选项。
LAN - 如果防火墙后面有任何可用的 LAN,我们将在本节中添加与其相关的选项。这是最有可能的,因此这部分几乎总是可用的。
DMZ - 如果有任何原因,我们将在此时添加 DMZ 区域配置。大多数脚本都缺少此部分,主要是因为任何正常的家庭网络或小型公司网络都不会包含此部分。
本地主机- 这些选项与我们的本地主机有关。这些变量不太可能改变,但无论如何我们已经将其中大部分放入变量中。希望没有理由改变这些变量。
iptables - 此部分包含 iptables 特定配置。在大多数脚本和情况下,这只需要一个变量来告诉我们 iptables 二进制文件的位置。
其他- 如果有任何其他特定选项和变量,则应首先将它们安装到正确的小节中(如果涉及互联网连接,则应在那里进行小节等)。如果它不适合任何地方,则应将其直接细分到某处的配置选项。
Configuration - First of all we have the configuration options which the rest of the script should use. Configuration options should pretty much always be the first thing in any shell-script.
Internet - This is the configuration section which pertains to the Internet connection. This could be skipped if we do not have any Internet connection. Note that there may be more subsections than those listed here, but only such that pertain to our Internet connection.
DHCP - If there are possibly any special DHCP requirements with this specific script, we will add the DHCP specific configuration options here.
PPPoE - If there is a possibility that the user that wants to use this specific script, and if there are any special circumstances that raises the chances that he is using a PPPoE connection, we will add specific options for those here.
LAN - If there is any LAN available behind the firewall, we will add options pertaining to that in this section. This is most likely, hence this section will almost always be available.
DMZ - If there is any reason to it, we will add a DMZ zone configuration at this point. Most scripts lacks this section, mainly because any normal home network, or small corporate network, will not have one.
Localhost - These options pertain to our localhost. These variables are highly unlikely to change, but we have put most of it into variables anyway. Hopefully, there should be no reason to change these variables.
iptables - This section contains iptables specific configuration. In most scripts and situations this should only require one variable which tells us where the iptables binary is located.
Other - If there are any other specific options and variables, they should first of all be fitted into the correct subsection (If it pertains to the Internet connection, it should be sub-sectioned there, etc). If it does not fit in anywhere, it should be sub-sectioned directly to the configuration options somewhere.
模块加载- 这部分脚本应维护模块列表。第一部分应包含必需的模块,而第二部分应包含非必需的模块。
请注意,某些可能提高安全性或添加某些服务或可能性的模块可能已被添加,即使它们不是必需的。在这种情况下,通常应该在示例脚本中注明这一点。 |
从更高版本的 iptables 开始,模块是自动加载的,大多数模块不需要加载,但从控制角度来看,最好自己加载模块。例如,conntrack 助手永远不会自动加载。 |
所需模块- 此部分应包含所需模块,可能还包含添加安全性或向管理员或客户端添加特殊服务的特殊模块。
非必需模块- 本节包含正常操作不需要的模块。所有这些模块都应默认注释掉,如果您想添加它提供的服务,则由您决定。
Module loading - This section of the scripts should maintain a list of modules. The first part should contain the required modules, while the second part should contain the non-required modules.
Note that some modules that may raise security, or add certain services or possibilities, may have been added even though they are not required. This should normally be noted in such cases within the example scripts. |
As of the later iptables versions, modules are automatically loaded and most module loading should not be required, but from a control perspective, it is better to load the modules on your own. For example, the conntrack helpers are never automatically loaded. |
Required modules - This section should contain the required modules, and possibly special modules that add to the security or add special services to the administrator or clients.
Non-required modules - This section contains modules that are not required for normal operations. All of these modules should be commented out per default, and if you want to add the service it provides, it is up to you.
proc 配置- 此部分应处理 proc 文件系统中所需的任何特殊配置。如果需要其中一些选项,它们将按原样列出,如果不需要,则应默认注释掉它们,并在非必需的过程配置下列出。大多数有用的过程配置将在这里列出,但远不是全部。
所需的 proc 配置- 此部分应包含相关脚本正常工作所需的所有 proc 配置。它还可能包含提高安全性的配置,并且可能为管理员或客户端添加特殊服务或可能性。
非必需的 proc 配置- 本节应包含可能有用的非必需的 proc 配置。所有这些都应该被注释掉,因为它们实际上并不是使脚本正常工作所必需的。该列表将包含远非所有的过程配置或节点。
proc configuration - This section should take care of any special configuration needed in the proc file system. If some of these options are required, they will be listed as such, if not, they should be commented out per default, and listed under the non-required proc configurations. Most of the useful proc configurations will be listed here, but far from all of them.
Required proc configuration - This section should contain all of the required proc configurations for the script in question to work. It could possibly also contain configurations that raise security, and possibly which add special services or possibilities for the administrator or clients.
Non-required proc configuration - This section should contain non-required proc configurations that may prove useful. All of them should be commented out, since they are not actually necessary to get the script to work. This list will contain far from all of the proc configurations or nodes.
规则设置- 到目前为止,脚本很可能已经准备好插入规则集。我选择将所有规则拆分到表格之后,然后将名称链接到规则集中,以使它们更易于遵循和阅读。所有用户指定的链都是在我们对链中内置的系统执行任何操作之前创建的。我还选择按照 iptables -L 命令输出的顺序设置链及其规则规范。
过滤表 - 首先我们浏览过滤表及其内容。首先我们应该设置表中的所有策略。
设置策略- 设置系统链的所有默认策略。通常我会在过滤器表中的 chaina 上设置 DROP 策略,特别是接受我想要允许进入的服务和流。这样我们就可以摆脱所有我们不想让人们使用的端口。
创建用户指定的链- 此时,我们创建稍后要在此表中使用的所有用户指定的链。如果这些链尚未创建,我们将无法在系统链中使用它们,因此我们最好尽快使用它们。
在用户指定的链中创建内容 - 创建用户指定的链后,我们也可以在这些链中输入所有规则。我此时必须输入此数据的唯一原因是您也可以将其放在用户指定链的创建附近。您也可以稍后将其添加到您的脚本中,这完全取决于您。
INPUT 链- 当我们走到这一步时,我们在过滤器表中没有太多事情要做,因此我们进入 INPUT 链。此时我们应该添加 INPUT 链中的所有规则。
此时,我们开始跟踪 iptables -L 命令的输出,如您所见。您没有理由继续使用这种结构,但是,请尽量避免混合来自不同表和链的数据,因为读取此类规则集和修复可能的问题将变得更加困难。 |
FORWARD 链- 此时我们继续在 FORWARD 链中添加规则。这个决定没什么特别的。
OUTPUT 链- 最后在过滤器表中,我们添加处理 OUTPUT 链的规则。希望此时不需要做太多事情。
nat 表- 在过滤器表之后,我们处理 nat 表。由于这些脚本中的多种原因,这是在过滤表之后完成的。首先,我们不希望过早地开启整个转发机制和NAT功能,这可能会导致数据包在错误的时间点(即当NAT已开启时,但没有运行任何过滤规则)。另外,我将 nat 表视为一种位于过滤器表外部并围绕它的层。因此,过滤表将成为核心,而 nat 表充当过滤表周围的一层,最后,mangle 表作为第二层位于 nat 表周围。从某些角度来看,这可能是错误的,但与现实相差不远。
设置策略- 首先,我们在 nat 表中设置所有默认策略。通常,我会对一开始设置的默认策略感到满意,即 ACCEPT 策略。无论如何,这个表不应该被用来过滤,我们也不应该让数据包被丢弃在这里,因为在这种情况下,由于我们自己的假设,可能会发生一些非常令人讨厌的事情。我将这些链设置为“接受”,因为没有理由不这样做。
创建用户指定的链- 此时,我们在 nat 表中创建我们想要的任何用户指定的链。通常我没有这些,但我还是添加了这一部分,以防万一。请注意,必须先创建用户指定的链,然后才能在系统链中实际使用它们。
在用户指定的链中创建内容- 现在应该将所有规则添加到 nat 表中的用户指定的链中。这里的情况与过滤器表中用户指定的链相同。我们在此添加此材料,因为我认为没有任何理由不这样做。
PREROUTING 链- PREROUTING 链用于在数据包上进行 DNAT,以防我们需要它。在大多数脚本中,这个功能没有被使用,或者至少被注释掉了。原因是我们不想在不知情的情况下给我们的本地网络打开大漏洞。在某些脚本中,我们默认启用此功能,因为这些脚本的唯一目的是提供此类服务。
POSTROUTING 链- POSTROUTING 链应该可以很好地被我编写的脚本使用,因为它们中的大多数都依赖于这样一个事实:您有一个或多个本地网络,我们希望对这些网络进行防火墙以抵御 Internet。主要我们会尝试使用 SNAT 目标,但在某些情况下我们被迫使用 MASQUERADE 目标。
OUTPUT 链 - OUTPUT 链在任何脚本中都几乎没有使用。现在看来,它并没有坏,但到目前为止我还找不到任何充分的理由来使用这条链。如果有人有理由使用这个链,请给我发一封信,我会将其添加到教程中。
mangle 表 - 最后一个要处理的表是 mangle 表。通常我根本不会使用这个表,因为它通常不应该被任何人使用,除非他们有特定的需求,例如屏蔽所有框以使用完全相同的 TTL 或更改 TOS 字段等。换句话说,我选择了将脚本的这些部分或多或少留空,除了一些例外,我添加了一些它可能用途的示例。
设置策略- 设置链内的默认策略。这里的情况与 nat 表几乎相同。该表不是为过滤而设计的,因此您应该完全避免使用它。我没有以某种方式在 mangle 表中的任何脚本中设置任何策略,并且鼓励您也不要这样做。
创建用户指定的链- 创建所有用户指定的链。由于我在脚本中几乎没有使用过 mangle 表,因此我也没有在这里创建任何链,因为如果没有任何数据可在其中使用,它是相当无法使用的。但是,添加此部分是为了以防万一某人或我将来需要它。
在用户指定的链中创建内容- 如果您在此表中有任何用户指定的链,此时您可以在其中添加所需的规则。
PREROUTING- 此时,本教程中的任何脚本中几乎没有任何包含此处规则的信息。基本上,PREROUTING 链可用于设置 netfilter、路由和 SEC 标记,既可以基于每个数据包,也可以基于每个连接。
INPUT 链- INPUT 链在本教程的当前脚本中几乎没有使用,但它可以用于标记处理等。
FORWARD 链- mangle 表的 FORWARD 链可用于标记处理和修改穿过相关防火墙的数据包的数据包标头。例如更改 TTL 和 TOS。
OUTPUT 链- OUTPUT 链可用于破坏离开防火墙或主机本身的数据包,例如设置不同的标记或设置 TTL 或 TOS 值。这里的大多数脚本都没有这样做,但是已经添加了该部分。
POSTROUTING 链- 在编写本文时,本教程中的任何脚本基本上都没有使用该链,但它可用于设置离开主机或防火墙本身的所有数据包以及穿越机器的流量的值。例如,它可用于重置数据包的 MTU、设置 TTL 或 TOS 等。
Rules set up - By now the scripts should most probably be ready to insert the rule-set. I have chosen to split all the rules down after table and then chain names in the rule-sets, to make them easier to follow and read. All user specified chains are created before we do anything to the system built in chains. I have also chosen to set the chains and their rule specifications in the same order as they are output by the iptables -L command.
Filter table - First of all we go through the filter table and its content. First of all we should set up all the policies in the table.
Set policies - Set up all the default policies for the system chains. Normally I will set DROP policies on the chainsa in the filter table, and specifically ACCEPT services and streams that I want to allow inside. This way we will get rid of all ports that we do not want to let people use.
Create user specified chains - At this point we create all the user specified chains that we want to use later on within this table. We will not be able to use these chains in the system chains anyway if they are not already created so we might as well get to it as soon as possible.
Create content in user specified chains - After creating the user specified chains we may as well enter all the rules within these chains. The only reason I have to enter this data at this point already is that you may as well put it close to the creation of the user specified chains. You may as well put this later on in your script, it is totally up to you.
INPUT chain - When we have come this far, we do not have a lot of things left to do within the filter table so we get onto the INPUT chain. At this point we should add all rules within the INPUT chain.
At this point we start following the output from the iptables -L command as you may see. There is no reason for you to stay with this structure, however, do try to avoid mixing up data from different tables and chains since it will become much harder to read such rule-sets and to fix possible problems. |
FORWARD chain - At this point we go on to add the rules within the FORWARD chain. Nothing special about this decision.
OUTPUT chain - Last of all in the filter table, we add the rules dealing with the OUTPUT chain. There should, hopefully, not be too much to do at this point.
nat table - After the filter table we take care of the nat table. This is done after the filter table because of a number of reasons within these scripts. First of all we do not want to turn the whole forwarding mechanism and NAT function on at too early a stage, which could possibly lead to packets getting through the firewall at just the wrong time point (i.e., when the NAT has been turned on, but none of the filter rules has been run). Also, I look upon the nat table as a sort of layer that lies just outside the filter table and kind of surrounds it. The filter table would hence be the core, while the nat table acts as a layer lying around the filter table, and finally the mangle table lies around the nat table as a second layer. This may be wrong in some perspectives, but not too far from reality.
Set policies - First of all we set up all the default policies within the nat table. Normally, I will be satisfied with the default policy set from the beginning, namely the ACCEPT policy. This table should not be used for filtering anyways, and we should not let packets be dropped here since there are some really nasty things that may happen in such cases due to our own presumptions. I let these chains be set to ACCEPT since there is no reason not to do so.
Create user specified chains - At this point we create any user specified chains that we want within the nat table. Normally I do not have any of these, but I have added this section anyways, just in case. Note that the user specified chains must be created before they can actually be used within the system chains.
Create content in user specified chains - By now it should be time to add all the rules to the user specified chains in the nat table. The same thing goes here as for the user specified chains in the filter table. We add this material here since I do not see any reason not to.
PREROUTING chain - The PREROUTING chain is used to do DNAT on packets in case we have a need for it. In most scripts this feature is not used, or at the very least commented out. The reason being that we do not want to open up big holes to our local network without knowing about it. Within some scripts we have this turned on by default since the sole purpose of those scripts is to provide such services.
POSTROUTING chain - The POSTROUTING chain should be fairly well used by the scripts I have written since most of them depend upon the fact that you have one or more local networks that we want to firewall against the Internet. Mainly we will try to use the SNAT target, but in certain cases we are forced to use the MASQUERADE target instead.
OUTPUT chain - The OUTPUT chain is barely used at all in any of the scripts. As it looks now, it is not broken, but I have been unable to find any good reasons to use this chain so far. If anyone has a reason to use this chain, send me a line and I will add it to the tutorial.
mangle table - The last table to do anything about is the mangle table. Normally I will not use this table at all, since it should normally not be used for anyone, unless they have specific needs, such as masking all boxes to use the exact same TTL or to change TOS fields etc. I have in other words chosen to leave these parts of the scripts more or less blank, with a few exceptions where I have added a few examples of what it may be used for.
Set policies - Set the default policies within the chain. The same thing goes here as for the nat table, pretty much. The table was not made for filtering, and hence you should avoid it alltogether. I have not set any policies in any of the scripts in the mangle table one way or the other, and you are encouraged not to do so either.
Create user specified chains - Create all the user specified chains. Since I have barely used the mangle table at all in the scripts, I have neither created any chains here since it is fairly unusable without any data to use within it. However, this section was added just in case someone, or I, would have the need for it in the future.
Create content in user specified chains - If you have any user specified chains within this table, you may at this point add the rules that you want within them here.
PREROUTING - At this point there is barely any information in any of the scripts in this tutorial that contains any rules here. Basically, the PREROUTING chain can be used to set netfilter, routing and SEC marks, both on a per packet basis and on a per connection basis.
INPUT chain - The INPUT chain is barely used in the current scripts of the tutorial, but it could be used for mark handling for example.
FORWARD chain - The FORWARD chain of the mangle table can be used for mark handling and for mangling packet headers of packets that are traveling across the firewall in question. Changing TTL and TOS for example.
OUTPUT chain - The OUTPUT chain could be used to mangle the packets leaving the firewall or host itself, for example setting different marks or setting TTL or TOS values. This is not done in most of the scripts here, but the section has been added however.
POSTROUTING chain - This chain is basically not in use by any of the scripts in the tutorial as of writing this, but it could be used to setting values for all packets leaving both the host or firewall itself, and traffic traversing the machine. For example, it could be used to reset the MTU of packets, set TTL or TOS et cetera.
希望这应该更详细地解释每个脚本的结构以及为什么以这种方式构建它们。
Hopefully this should explain more in detail how each script is structured and why they are structured in such a way.
请注意,这些描述非常简短,主要应该被视为对脚本被拆分的内容和原因的简短解释。没有任何证据表明这是唯一且最好的方法。 Do note that these descriptions are extremely brief, and should mainly just be seen as a brief explanation to what and why the scripts have been split down as they have. There is nothing that says that this is the only and best way to go. |
rc.firewall.txt脚本是其余脚本所基于的主要核心。rc.firewall文件章节应该最彻底地解释脚本中的每个细节。它主要是为双宿主网络编写的。例如,您有一个 LAN 和一个 Internet 连接。该脚本还假设您拥有 Internet 的静态 IP,因此不要使用 DHCP、PPP、SLIP 或其他自动为您分配 IP 的协议。如果您正在寻找适用于这些设置的脚本,请仔细查看rc.DHCP.firewall.txt脚本。
The rc.firewall.txt script is the main core on which the rest of the scripts are based upon. The rc.firewall file chapter should explain every detail in the script most thoroughly. Mainly it was written for a dual homed network. For example, where you have one LAN and one Internet Connection. This script also makes the assumption that you have a static IP to the Internet, and hence don't use DHCP, PPP, SLIP or some other protocol that assigns you an IP automatically. If you are looking for a script that will work with those setups, please take a closer look at the rc.DHCP.firewall.txt script.
rc.firewall.txt 脚本需要将以下选项静态编译到内核或作为模块。如果没有其中一项或多项,脚本将或多或少地存在缺陷,因为脚本所需的部分功能将无法使用。当您更改所使用的脚本时,您可能需要将更多选项编译到内核中,具体取决于您要使用的内容。
The rc.firewall.txt script requires the following options to be compiled statically to the kernel, or as modules. Without one or more of these, the script will become more or less flawed since parts of the script's required functionalities will be unusable. As you change the script you use, you could possibly need more options to be compiled into your kernel depending on what you want to use.
配置网络过滤器
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_FILTER
配置_IP_NF_NAT
CONFIG_IP_NF_NAT
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_TARGET_LOG
rc.DMZ.firewall.txt _脚本是为那些拥有一个受信任的内部网络、一个非军事区和一个互联网连接的人编写的。在这种情况下,非军事区是一对一的 NAT,并且要求您在防火墙上执行一些 IP 别名操作,即您必须使该设备能够识别多个 IP 的数据包。有多种方法可以使其发挥作用,一种是设置 1 对 1 NAT,如果您有整个子网,另一种方法是创建一个子网,为防火墙提供一个内部和外部 IP。然后,您可以根据需要将 IP 设置为 DMZ 框。请注意,这将为您“窃取”两个 IP,一个用于广播地址,一个用于网络地址。这很大程度上取决于您来决定和实施。本教程将为您提供实际完成防火墙和 NAT 部分的工具,
The rc.DMZ.firewall.txt script was written for those people out there that have one Trusted Internal Network, one De-Militarized Zone and one Internet Connection. The De-Militarized Zone is in this case 1-to-1 NATed and requires you to do some IP aliasing on your firewall, i.e., you must make the box recognize packets for more than one IP. There are several ways to get this to work, one is to set 1-to-1 NAT, another one if you have a whole subnet is to create a subnetwork, giving the firewall one IP both internally and externally. You could then set the IP's to the DMZed boxes as you wish. Do note that this will "steal" two IP's for you, one for the broadcast address and one for the network address. This is pretty much up to you to decide and to implement. This tutorial will give you the tools to actually accomplish the firewalling and NATing part, but it will not tell you exactly what you need to do since it is out of the scope of the tutorial.
rc.DMZ.firewall.txt 脚本需要将这些选项静态或作为模块编译到内核中。如果没有这些选项,至少在您的内核中可用,您将无法使用此脚本功能。换句话说,您可能会收到很多错误,抱怨模块和目标/跳转或匹配丢失。如果您计划进行流量控制或任何其他类似的事情,您应该确保将所有必需的选项也编译到内核中。
The rc.DMZ.firewall.txt script requires these options to be compiled into your kernel, either statically or as modules. Without these options, at the very least, available in your kernel, you will not be able to use this scripts functionality. You may in other words get a lot of errors complaining about modules and targets/jumps or matches missing. If you are planning to do traffic control or any other things like that, you should see to it that you have all the required options compiled into your kernel there as well.
配置网络过滤器
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_FILTER
配置_IP_NF_NAT
CONFIG_IP_NF_NAT
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_TARGET_LOG
正如您从图片中看到的那样,您需要使用此脚本有两个内部网络。其中一个使用 IP 范围 192.168.0.0/24,并由可信内部网络组成。另一个使用 IP 范围 192.168.1.0/24,由非军事区组成,我们将对其进行 1 对 1 NAT。例如,如果来自 Internet 的某人向我们的 发送数据包DNS_IP,则我们使用 DNAT 将数据包发送到 DMZ 网络上的 DNS。当 DNS 看到我们的数据包时,该数据包将发往实际的 DNS 内部网络 IP,而不是我们的外部 DNS IP。如果数据包没有被转换,DNS 将不会应答该数据包。我们将展示 DNAT 代码的一个简短示例:
You need to have two internal networks with this script as you can see from the
picture. One uses IP range 192.168.0.0/24 and consists of a Trusted
Internal Network. The other one uses IP range 192.168.1.0/24 and
consists of the De-Militarized Zone which we will do
1-to-1 NAT to. For example, if someone from the
Internet sends a packet to our DNS_IP, then we use
DNAT to send the packet on to our
DNS on the DMZ network. When
the DNS sees our packet, the packet will be destined
for the actual DNS internal network IP, and not to our
external DNS IP. If the packet would not have been
translated, the DNS wouldn't have answered the packet.
We will show a short example of how the DNAT code
looks:
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP \
--dport 53 -j DNAT --到目的地 $DMZ_DNS_IP
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP \
--dport 53 -j DNAT --to-destination $DMZ_DNS_IP
首先,DNAT只能在nat表的PREROUTING链中进行。$INET_IFACE然后,我们在我们的目标 IP
上查找与我们的 匹配的 TCP 协议
$DNS_IP,并定向到端口 53,这是用于名称服务器之间区域传输的 TCP 端口。如果我们确实收到这样的数据包,我们就会给出 DNAT 的目标。之后,我们使用 --to-destination 选项指定数据包的去向,并为其指定值$DMZ_DNS_IP,换句话说就是 DMZ 网络上 DNS 的 IP。这就是基本 DNAT 的工作原理。当 DNATed 数据包的回复通过防火墙发送时,它会自动取消 DNATed。
First of all, DNAT can only be performed in the
PREROUTING chain of the nat
table. Then we look for TCP protocol on our
$INET_IFACE with destination IP that matches our
$DNS_IP, and is directed to port 53, which is the
TCP port for zone transfers between name servers. If
we actually get such a packet we give a target of
DNAT. After that we specify where we want the packet
to go with the --to-destination option and give it the value
of $DMZ_DNS_IP, in other words the IP of the
DNS on our DMZ network. This
is how basic DNAT works. When the reply to the
DNATed packet is sent through the firewall, it
automatically gets un-DNATed.
到目前为止,您应该对一切的工作原理有足够的了解,以便能够很好地理解这个脚本,而不会出现任何巨大的复杂性。如果您不明白的内容在本教程的其余部分中尚未完成,请给我发邮件,因为这可能是我这边的错误。
By now you should have enough understanding of how everything works to be able to understand this script pretty well without any huge complications. If there is something you don't understand that hasn't been gone through in the rest of the tutorial, mail me since it is probably a fault on my side.
rc.DHCP.firewall.txt脚本与原始rc.firewall.txt几乎相同 。但是,此脚本不再使用 STATIC_IP 变量,这是对原始 rc.firewall.txt 脚本的主要更改。原因是这不能与动态 IP 连接一起使用。需要对原始脚本进行的实际更改很小,但是,有些人给我发邮件询问问题,因此该脚本将是您的一个很好的解决方案。该脚本将允许使用 DHCP、PPP 和 SLIP 连接的用户连接到 Internet。
The rc.DHCP.firewall.txt script is pretty much identical to the original rc.firewall.txt. However, this script no longer uses the STATIC_IP variable, which is the main change to the original rc.firewall.txt script. The reason is that this won't work together with a dynamic IP connection. The actual changes needed to be done to the original script are minimal, however, I've had some people mail me and ask about the problem so this script will be a good solution for you. This script will allow people who uses DHCP, PPP and SLIP connections to connect to the Internet.
rc.DHCP.firewall.txt脚本需要将以下选项静态编译到内核或作为模块,作为正常运行的最低要求 。
The rc.DHCP.firewall.txt script requires the following options to be compiled statically to the kernel, or as modules, as a bare minimum to run properly.
配置网络过滤器
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_FILTER
配置_IP_NF_NAT
CONFIG_IP_NF_NAT
CONFIG_IP_NF_TARGET_MASQUERADE
CONFIG_IP_NF_TARGET_MASQUERADE
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_TARGET_LOG
对脚本所做的主要更改包括删除变量
STATIC_IP(正如我已经说过的那样)以及删除对此变量的所有引用。现在,脚本不再使用此变量,而是对变量进行主要过滤INET_IFACE。换句话说,-d $STATIC_IP 已更改为 -i $INET_IFACE。这几乎是唯一所做的更改,这就是真正需要的全部更改。
The main changes done to the script consist of erasing the
STATIC_IP variable as I already said and deleting all
references to this variable. Instead of using this variable the script now
does its main filtering on the variable INET_IFACE. In
other words -d $STATIC_IP has been changed to -i
$INET_IFACE. This is pretty much the only change made and that's all
that's needed really.
不过,还有一些事情需要考虑。我们不能再根据 --in-interface $LAN_IFACE --dst $INET_IP 等在 INPUT 链中进行过滤。这反过来又迫使我们在内部机器必须访问互联网可寻址IP的情况下仅根据接口进行过滤。一个很好的例子是,如果我们在防火墙上运行 HTTP。如果我们转到主页(即http://192.168.0.1/),其中包含返回同一主机的静态链接(即http://foobar.dyndns.net/fuubar.html),这可能是一些 dyndns 解决方案,我们会遇到一个小问题。NAT 框会向 DNS 询问 HTTP 服务器的 IP,然后尝试访问该 IP。如果我们根据接口和 IP 进行过滤,则 NAT 盒将无法访问 HTTP,因为 INPUT 链会将数据包直接丢弃到地面。
INET_IP,如果是的话接受它们。
There are some more things to think about though. We can no longer filter in the
INPUT chain depending on, for example,
--in-interface $LAN_IFACE --dst $INET_IP. This in turn forces
us to filter only based on interfaces in such cases where the internal machines
must access the Internet addressable IP. One great example is if we are
running an HTTP on our firewall. If we go to the main
page (i.e., http://192.168.0.1/), which contains static links back to the same
host (i.e., http://foobar.dyndns.net/fuubar.html), which could be some dyndns
solution, we would get a minor problem. The
NATed box would ask the DNS
for the IP of the HTTP server, then try to access
that IP. In case we filter based on interface and IP, the
NATed box would be unable to get to the
HTTP because the INPUT chain
would DROP the packets flat to the ground. This also
applies in a sense to the case where we got a static IP, but in such cases it
could be gotten around by adding rules which check the
LAN interface packets for our
INET_IP, and if so ACCEPT them.
正如您可能从上面读到的,获取一个脚本或编写一个脚本来更好地处理动态 IP 可能是一个好主意。例如,我们可以编写一个脚本,在互联网连接启动时从 ifconfig 获取 IP 并将其添加到变量中。一个好的方法是使用pppd 和其他一些程序提供的ip-up脚本。要找到一个好的站点,请查看 linuxguruz.org iptables 站点,该站点有大量可供下载的脚本。您可以从其他资源和链接附录中找到 linuxguruz.org 站点的链接 。
As you may read from above, it may be a good idea to get a script, or write one, that handles dynamic IP in a better sense. We could for example make a script that grabs the IP from ifconfig and adds it to a variable, upon boot-up of the Internet connection. A good way to do this, would be to use, for example, the ip-up scripts provided with pppd and some other programs. For a good site, check out the linuxguruz.org iptables site which has a huge collection of scripts available to download. You will find a link to the linuxguruz.org site from the Other resources and links appendix.
该脚本可能比rc.firewall.txt脚本安全性稍差 。如果可能的话,我绝对建议您使用该脚本,因为该脚本更容易受到外部攻击。 This script might be a bit less secure than the rc.firewall.txt script. I would definitely advise you to use that script if at all possible since this script is more open to attacks from the outside. |
此外,还可以将类似的内容添加到您的脚本中:
Also, there is the possibility to add something like this to your scripts:
INET_IP=`ifconfig $INET_IFACE | grep inet | 剪切 -d : -f 2 | \
切 -d ' ' -f 1`
INET_IP=`ifconfig $INET_IFACE | grep inet | cut -d : -f 2 | \
cut -d ' ' -f 1`
上面的代码会自动获取 $INET_IFACE 变量的 IP 地址,grep 包含该 IP 地址的正确行,然后将其缩减为可管理的 IP 地址。对于更复杂的方法,您可以应用retreiveip.txt脚本中可用的代码片段,当您运行该脚本时,它将自动获取您的 Internet IP 地址。请注意,这可能会导致一些“奇怪”的行为,例如停止与内部防火墙之间的连接。下面的列表描述了最常见的奇怪行为。
The above would automatically grab the IP address of the $INET_IFACE variable, grep the correct line which contains the IP address and then cuts it down to a manageable IP address. For a more elaborate way of doing this, you could apply the snippets of code available within the retreiveip.txt script, which will automatically grab your Internet IP address when you run the script. Do note that this may in turn lead to a little bit of "weird" behavior, such as stalling connections to and from the firewall on the internal side. The most common strange behaviors are described in the following list.
如果该脚本是从脚本内部运行的,而该脚本又由 PPP 守护程序执行,则由于 NEW 而非 SYN 规则,它将挂起所有当前活动的连接(请参阅状态 NEW 数据包但没有 SYN 位设置部分) 。例如,如果您摆脱 NEW not SYN 规则,这是可能的,但这是值得怀疑的。
If the script is run from within a script which in turn is executed by, for example, the PPP daemon, it will hang all currently active connections due to the NEW not SYN rules (see the State NEW packets but no SYN bit set section). It is possible to get by, if you get rid of the NEW not SYN rules for example, but it is questionable.
如果你的规则是静态的并且总是想要存在,那么一直添加和删除规则而不损害已经存在的规则是相当苛刻的。例如,如果您想阻止 LAN 上的主机连接到防火墙,但同时从 PPP 守护程序运行脚本,您将如何做到这一点而不删除已经激活的阻止 LAN 的规则?
If you got rules that are static and always want to be around, it is rather harsh to add and erase rules all the time, without hurting the already existing ones. For example, if you want to block hosts on your LAN to connect to the firewall, but at the same time operate a script from the PPP daemon, how would you do it without erasing your already active rules blocking the LAN?
正如上面所见,它可能会变得不必要的复杂,这反过来又可能导致安全隐患。如果脚本保持简单,就更容易发现问题并保持其中的顺序。
It may get unnecessarily complicated, as seen above which, in turn, could lead to security compromises. If the script is kept simple, it is easier to spot problems, and to keep order in it.
与其他脚本相比, rc.UTIN.firewall.txt脚本会阻止我们身后的 LAN 。换句话说,我们不信任我们所连接的任何网络上的任何人。我们还禁止 LAN 上的人员在 Internet 上执行除特定任务之外的任何操作。我们实际上只允许通过 POP3、HTTP 和 FTP 访问 Internet。我们也不信任内部用户访问防火墙,而不是信任互联网上的用户。
The rc.UTIN.firewall.txt script will in contrast to the other scripts block the LAN that is sitting behind us. In other words, we don't trust anyone on any networks we are connected to. We also disallow people on our LAN to do anything but specific tasks on the Internet. The only things we actually allow are POP3, HTTP and FTP access to the Internet. We also don't trust the internal users to access the firewall more than we trust users on the Internet.
rc.UTIN.firewall.txt 脚本需要将以下选项静态编译到内核或作为模块。如果没有其中一项或多项,脚本将或多或少地存在缺陷,因为脚本所需的部分功能将无法使用。当您更改所使用的脚本时,您可能需要将更多选项编译到内核中,具体取决于您要使用的内容。
The rc.UTIN.firewall.txt script requires the following options to be compiled statically to the kernel, or as modules. Without one or more of these, the script will become more or less flawed since parts of the script's required functionalities will be unusable. As you change the script you use, you could possibly need more options to be compiled into your kernel depending on what you want to use.
配置网络过滤器
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_FILTER
配置_IP_NF_NAT
CONFIG_IP_NF_NAT
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_TARGET_LOG
该脚本遵循不信任任何人的黄金法则,甚至不信任我们自己的员工。这是一个令人悲伤的事实,但公司遭受的黑客攻击和破解很大一部分是由其自己的员工实施的。该脚本有望为您提供一些线索,让您了解如何使用防火墙来加强防火墙。它与原始的rc.firewall.txt脚本没有太大不同,但它确实给出了一些我们通常允许通过的提示等。
This script follows the golden rule to not trust anyone, not even our own employees. This is a sad fact, but a large part of the hacks and cracks that a company gets hit by are a matter of people from their own staff perpetrating the hit. This script will hopefully give you some clues as to what you can do with your firewall to strengthen it. It's not very different from the original rc.firewall.txt script, but it does give a few hints at what we would normally let through etc.
rc.test -iptables.txt脚本可用于测试所有不同的链,但它可能需要根据您的配置进行一些调整,例如打开 ip_forwarding 和设置伪装等。它适用于大多数拥有以下功能的人所有基本设置和所有基本表加载到内核中。它真正做的只是设置一些 LOG 目标,这些目标将记录 ping 回复和 ping 请求。这样,您将获得有关遍历哪条链以及遍历顺序的信息。例如,运行此脚本,然后执行以下操作:
The rc.test-iptables.txt script can be used to test all the different chains, but it might need some tweaking depending on your configuration, such as turning on ip_forwarding, and setting up masquerading etc. It will work for most everyone who has all the basic set up and all the basic tables loaded into kernel. All it really does is set some LOG targets which will log ping replies and ping requests. This way, you will get information on which chain was traversed and in which order. For example, run this script and then do:
ping -c 1 互联网上的主机
ping -c 1 host.on.the.internet
并在执行第一个命令时 tail -n 0 -f /var/log/messages 。这应该向您显示所使用的所有不同链及其顺序,除非日志条目由于某种原因被交换。
And tail -n 0 -f /var/log/messages while doing the first command. This should show you all the different chains used, and in which order, unless the log entries are swapped around for some reason.
该脚本仅为测试目的而编写。换句话说,使用这样的规则来记录一种类型的所有内容并不是一个好主意,因为您的日志分区可能会很快被填满,这将是针对您的有效拒绝服务攻击,并可能导致对您的真正攻击在最初的拒绝服务攻击后将被取消记录。 This script was written for testing purposes only. In other words, it's not a good idea to have rules like this that log everything of one sort since your log partitions might get filled up quickly and it would be an effective Denial of Service attack against you and might lead to real attacks on you that would be unlogged after the initial Denial of Service attack. |
rc.flush -iptables.txt脚本本身不应该真正被称为脚本。rc.flush -iptables.txt 脚本将重置并刷新所有表和链。该脚本首先将过滤器表的 INPUT、OUTPUT 和 FORWARD 链上的默认策略设置为 ACCEPT。之后,我们重置 nat 表的 PREROUTING、POSTROUTING 和 OUTPUT 链的默认策略。我们首先这样做,这样我们就不必担心关闭的连接和数据包无法通过。该脚本旨在实际设置防火墙并对其进行故障排除,因此我们只关心打开整个防火墙并将其重置为默认值。
The rc.flush-iptables.txt script should not really be called a script in itself. The rc.flush-iptables.txt script will reset and flush all your tables and chains. The script starts by setting the default policies to ACCEPT on the INPUT, OUTPUT and FORWARD chains of the filter table. After this we reset the default policies of the PREROUTING, POSTROUTING and OUTPUT chains of the nat table. We do this first so we won't have to bother about closed connections and packets not getting through. This script is intended for actually setting up and troubleshooting your firewall, and hence we only care about opening the whole thing up and resetting it to default values.
之后,我们首先刷新过滤器表中的所有链,然后刷新 NAT 表中的所有链。这样我们就知道任何地方都没有多余的规则。当所有这些完成后,我们跳到下一部分,删除 NAT 和过滤表中所有用户指定的链。完成此步骤后,我们认为脚本已完成。如果您使用它,您可以考虑添加规则来刷新您的 mangle 表。
After this we flush all chains first in the filter table and then in the NAT table. This way we know there are no redundant rules lying around anywhere. When all of this is done, we jump down to the next section where we erase all the user specified chains in the NAT and filter tables. When this step is done, we consider the script done. You may consider adding rules to flush your mangle table if you use it.
关于这个问题的最后一句话。某些人发邮件给我,要求我使用 Red Hat Linux 语法将此脚本放入原始 rc.firewall 脚本中,在其中键入 rc.firewall start 之类的内容,脚本就会启动。但是,我不会这样做,因为这是一个教程,应该主要用作获取想法的地方,并且不应该充满 shell 脚本和奇怪的语法。就我而言,添加 shell 脚本语法和其他内容会使脚本更难阅读,并且本教程在编写时考虑到了可读性,并将继续如此。 One final word on this issue. Certain people have mailed me asking me to put this script into the original rc.firewall script using Red Hat Linux syntax where you type something like rc.firewall start and the script starts. However, I will not do that since this is a tutorial and should be used as a place to fetch ideas mainly and it shouldn't be filled up with shell scripts and strange syntax. Adding shell script syntax and other things makes the script harder to read as far as I am concerned and the tutorial was written with readability in mind and will continue being so. |
limit-match.txt脚本 是一个次要测试脚本,可让您测试限制匹配并查看其工作原理。加载脚本,然后以不同的时间间隔发送 ping 数据包,查看哪些数据包通过,以及它们通过的频率。所有回显回复都将被阻止,直到再次达到突发限制的阈值。
The limit-match.txt script is a minor test script which will let you test the limit match and see how it works. Load the script up, and then send ping packets at different intervals to see which gets through, and how often they get through. All echo replies will be blocked until the threshold for the burst limit has again been reached.
pid -owner.txt 是一个小示例脚本,展示了如何使用 PID 所有者匹配。它没有做任何实际的事情,但您应该能够运行该脚本,然后从 iptables -L -v 的输出中能够知道该规则实际上匹配。
The pid-owner.txt is a small example script that shows how we could use the PID owner match. It does nothing real, but you should be able to run the script, and then from the output of iptables -L -v be able to tell that the rule actually matches.
centre -match.txt脚本是如何使用最近匹配的一个小示例。有关此脚本的完整说明,请查看Iptables 匹配章节中的最近匹配部分。
The recent-match.txt script is a small example of how the recent match can be used. For a complete explanation of this script take a look at the Recent match section in the Iptables matches chapter.
sid -owner.txt 是一个小示例脚本,展示了如何使用 SID 所有者匹配。它没有做任何实际的事情,但您应该能够运行该脚本,然后从 iptables -L -v 的输出中能够知道该规则实际上匹配。
The sid-owner.txt is a small example script that shows how we could use the SID owner match. It does nothing real, but you should be able to run the script, and then from the output of iptables -L -v be able to tell that the rule actually matches.
一个小示例ttl-inc.txt 脚本。该脚本展示了如何使防火墙/路由器对跟踪路由不可见,否则会向可能的攻击者泄露大量信息。
A small example ttl-inc.txt script. This script shows how we could make the firewall/router invisible to traceroutes, which would otherwise reveal much information to possible attackers.
保存和恢复大型规则集一章中使用的小示例脚本,用于说明如何使用 iptables-save。该脚本不起作用,因此除了参考之外不应用于其他任何用途。
A small example script used in the Saving and restoring large rule-sets chapter to illustrate how iptables-save may be used. This script is non-working, and should hence not be used for anything else than a reference.
您刚刚阅读的章节基本上让您简要了解了本教程中提供的所有不同脚本以及它们试图向您传达的基本思想。希望它至少能够解释一些事情。
The chapter you have just read basically gave you a brief overlook of all the different scripts that are available with this tutorial and the basic idea that they are trying to bring across to you. Hopefully it has been able to explain something at the very least.
下一章将讨论 iptables 和 netfilter 可用的一些不同的图形用户界面。这远不是所有可用不同接口的完整列表,但正如您所看到的,还有很多其他接口。这些接口主要试图简化为您创建 iptables 脚本的过程,对于简单的设置来说,它们在大多数情况下都足够了。有时,您可能有更高、更复杂的需求,但您必须编写自己的脚本。
The next chapter will discuss some different graphical user interfaces that are available for iptables and netfilter. This is far from a complete listing of all the different interfaces available, but as you can see, there are quite a lot of othem. These interfaces mostly tries to simplify creating iptables scripts for you, and for simple setups they are more than enough most of the time. At other times, you may have higher and more complex needs and you must have to write your own script none the less.
我们尚未深入研究 iptables 和 netfilter 的一方面是可用于 iptables 和 netfilter 的图形用户界面。最大的问题之一是 netfilter 是一个非常复杂和灵活的设置,它可以执行最奇怪的任务。因此,为 netfilter 创建 GUI 可能成为一项非常艰巨的任务。
One side of iptables and netfilter that we haven't looked at very much yet, is the graphical user interfaces that are available for iptables and netfilter. One of the biggest problems with this is that netfilter is a very complex and flexible setup, that can perform the strangest of tasks. For this reason, it can become a very daunting task to create a GUI for netfilter.
一些个人和组织尝试为 netfilter 和 iptables 创建 GUI,有些人比其他人更成功,而另一些人在一段时间后就放弃了。每个人的尝试背后都有不同的理由,因此向所有人展示它们并不是一件容易的事。然而,本章是一些 iptables 和 netfilter 的 GUI 的小型汇编,可能值得一看。随时欢迎其他人提出添加建议。
Several persons and organisations have tried to create GUI's for netfilter and iptables, and some have succeeded better than others, while others have given up after some time. All have different reasoning behind their tries as well, so it isn't an easy task to show them all. However, this chapter is a small compilation of some of the GUI's for iptables and netfilter that may be worth looking at. Suggestions on others to add are always welcome.
Firewall Builder,或简称为 fwbuilder,是一个极其通用且功能强大的工具,可用于构建您自己的防火墙,或维护多个防火墙。它可用于为多种不同类型的防火墙创建策略,包括 iptables(Linux 2.4 和 2.6)、ipfilter(freebsd、netbsd 等)、openbsd pf 以及必须购买的模块 Cisco PIX。
Firewall Builder, or simply fwbuilder, is an extremely versatile and powerful tool that can be used to build your own firewalls, or to maintain several firewalls for that matter. It can be used to create policies for several different types of firewalls, including iptables (Linux 2.4 and 2.6), ipfilter (freebsd, netbsd, etc), openbsd pf, and, a module that must be bought, Cisco PIX.
正如您所看到的,Fwbuilder 拥有非常多的受众,并且得到了很好的照顾并不断得到开发。它在单独的主机系统上运行,您可以在其中创建策略文件,然后将它们复制到目标系统上并运行它们。它能够处理从非常简单的规则集到大型且相当复杂的规则集的所有内容。它具有处理不同版本和安装的 iptables 的广泛能力,通过配置每个主机系统上可用的目标/匹配等。最终结果可以保存在 xml 文件或系统可解析配置文件(例如,真实的防火墙脚本)中。
Fwbuilder has, as you can see, a very big audience and is well taken care of and continues to be developed. It is run on a separate host system, where you create the policy files, and then copy them over and run them on the target system. It is able to handle everything from very simple rulesets to large and rather complicated ones. It has extensive abilities to handle different versions and installations of iptables, by configuration of which targets/matches are available on each host system, etcetera. The end result may be saved in an xml file, or a system parsable configuration file (e.g., the real firewall scripts).
您可以在上面的示例中看到“防火墙”的配置,以及整个fwbuilder系统的主菜单。fwbuilder 可以在http://www.fwbuilder.org找到。
You can see the configuration of the "firewall" in the above example, and the main menus of the whole fwbuilder system. fwbuilder can be found at http://www.fwbuilder.org.
Turtle Firewall 是一种优秀但更简单的 iptables 用户界面。它集成在名为 webmin(Web 管理界面)的东西中。它相当基础,既不像 fwbuilder 包那样复杂,也不能处理复杂的更改,但它足以处理最简单的防火墙以及一些更高级的防火墙。
Turtle Firewall is an excellent, yet simpler kind of user interface to iptables. It is integrated in something called webmin (a web administration interface). It is fairly basic, and neither as complex nor able to handle as complex changes as the fwbuilder package, but it is more than able to handle most simpler firewalls, as well as some more advanced ones as well.
Turtle Firewall 的一大优势是它基于 Web,因此可以通过与 fwbuilder 和大多数其他工具完全不同的方式进行远程控制。当然,它也增加了更多的安全风险,因为 webmin 是在防火墙本身上运行的单独的额外服务。
One big advantage with Turtle Firewall is the fact that it is web-based, and hence can be remotely controlled in a totally different manner than with fwbuilder and most other tools. Of course, it also adds more of a security risk since webmin is a separate extra service running on the firewall itself.
上面的截图显示了Turtle Firewall的项目页面,您可以在其中配置网络接口和网络以及其他项目。
The above screenshot shows the items page of the Turtle Firewall, where you can configure network interfaces and networks, and other items.
最后的屏幕截图显示了turtlefirewalls的主屏幕,整个规则集在底部展开。如您所见,整个规则集并未显示,但您可以大致了解它在 Turtle Firewall 中的外观。
This final screenshot shows the turtlefirewalls main screen, and with the whole ruleset expanded at the bottom. The whole ruleset isn't showing, as you can see, but you get a good general idea of what it looks like in Turtle Firewall.
您可以在http://www.turtlefirewall.com/找到 Turtle Firewall 项目和更多信息。
You can find the Turtle Firewall Project and more information over at http://www.turtlefirewall.com/.
综合安全通信系统(简称ISCS)仍在开发中,尚未发布公共版本。然而,一旦完成,它看起来将成为一个非常有用的工具。开发商的标准非常高,这也是它迟迟没有发布的主要原因。ISCS 将多种功能集成到一套管理和管理用户界面中。基本上,这意味着一旦该项目发布,您将能够使用单个 GUI 从一个集中点完全配置所有防火墙,包括 VPN、VLAN、隧道、sysctl 等。
The Integrated Secure Communications System, or shortly ISCS, is still undergoing development, and no public version has been released. However, this looks like it will become an extremely helpful tool once it is finished. The developer has very high standards, and this is the main reason that it has not been released yet. ISCS integrates several functionalities into a single suite of administration and management user interface. Basically this means that once this project is released, you will be able to fully configure all your firewalls from a centralized point using a single GUI, including VPN's, VLAN's, Tunnels, sysctl's, etcetera.
ISCS开发者的主要攻击角度是简化管理和管理,消除管理员的繁琐工作,从而为管理员节省尽可能多的工作时间。这是通过将策略放在一起来完成的,然后程序创建规则集并将它们“推送”到“执行点”(例如,防火墙、代理等)。管理员实际上并不“编写”或“单击”规则集,只是简单地将策略放在一起,然后由 ISCS 强制执行。
The main attack angle that the developer(s) of ISCS has, is to simplify management and administration and to remove tedious work for the administrators, so to save as much work hours as possible for the administrators. This is done by putting together policies, and then the programs creates the rulesets and "pushes" them out to the "enforcements points" (e.g., firewalls, proxies, etcetera). The administrator doesn't actually "write" or "click" together the rulesets, just simply put together policies that are then enforced by ISCS.
截至撰写本文时,该工具尚未完成。不过,我之前已经和这个项目的主要开发者接触过,这确实是一个非常大的项目。当它完成后,我相信这将是市场上最好的工具之一。当然,时间只能证明一切,但这里非常值得一提。您可以在http://iscs.sourceforge.net/找到 ISCS 项目。
This tool isn't finished yet, as of writing this. However, I have been in touch with the main developer of this project before, and this is indeed a very large project. When it is finished, I believe this will be one of the best tools on the market. Of course, time can only tell, but it is well worth mentioning here. You can find the ISCS project over at http://iscs.sourceforge.net/.
ISCS 的主要开发人员 John Sullivan 特别要求我邀请人们加入他的开发工作。这个项目非常大,他肯定希望获得尽可能多的帮助。换句话说,如果您能够提供帮助,我们非常欢迎您。 The main developer, John Sullivan, of ISCS has specifically asked me to ask people to join his development efforts. The project is very big, and he would definitely like as much help with the project as possible. If you are able to help, you are, in other words, more than welcome. |
IPMenu 是一个非常强大的程序,但操作简单,对资源和带宽要求不高。它是一个基于控制台的程序,因此它可以通过 SSH 连接完美运行。它也可以在运行简单而旧的调制解调器的机器上完美运行。
IPMenu is a very able program, yet simple to operate and not too demanding on resources nor bandwidth. It is a console based program, so it works perfect over an SSH connection for example. It works perfectly on machines running over a simple and old modem as well.
正如您从屏幕截图中看到的,它能够处理所有 iptables 功能,包括过滤、修改和嵌套。它还能够处理路由表和带宽整形以及保存和恢复规则集。您可以轻松地将新规则直接添加到当前运行的 iptables 脚本中,并处理所有不同的表。包括添加和删除自定义链。
As you can see from the screenshot, it is able to handle all iptables functionality, including filtering, mangling and nating. It is also able to handle routing tables and bandwidth shaping and to save and restore rulesets. You can add new rules directly into the currently running iptables script easily, and handle all of the different tables. Including adding and removing custom chains.
从上面的屏幕截图中可以看出,该程序相当基础,但仍然能够很好地处理大多数情况。首先,它非常简单,并且可以足够简单地用于远程管理,并且由于它通过标准控制台在 ssh 之上运行,因此它也应该相当安全。您可以在http://users.pandora.be/stes/ipmenu.html找到 IPMenu 的主页。
As you can see from the screenshot above, the program is rather basic, but still able to handle most situations rather well. And first of all, it is very simple, and can be used for remote administration simply enough, and since it runs on top of ssh via a standard console, it should also be fairly secure. You can find the homepage of IPMenu at http://users.pandora.be/stes/ipmenu.html.
Easy Firewall Generator 是 iptables 和 netfilter 方面的另一个有趣的开发。基本上,Easy Firewall Generator 是一个 PHP 网页,您可以在其中指定防火墙的选项和细节,完成所有配置后,单击一个按钮,该网页就会显示一个您可以使用的 iptables 规则集。
Easy Firewall Generator is another interesting development when it comes to iptables and netfilter. Basically, Easy Firewall Generator is a PHP webpage where you specify options and specifics of your firewall, and once all of the configurations are done, you click a button, and the webpage spits out an iptables ruleset that you can utilize.
该脚本包含所有基本规则,以及包含数据包中奇怪模式的更具体规则。它还包含可能需要的特定 IP sysctl 更改、加载必要的模块等。整个规则集也是以 redhat init.d 格式编写的。
The script contains all the basic rules, and more specific ones to contain strange patterns in packets. It also contains specific IP sysctl changes that may be needed, loads necessary modules, et cetera. The whole ruleset is also written in a redhat init.d format.
此屏幕截图显示了配置即将由脚本创建的防火墙脚本的最后阶段之一。您可以在http://easyfwgen.morizot.net/上找到更多信息以及 Easy Firewall Generator 的工作版本。
This screenshot shows one of the final stages of configuring the firewall script that is about to be created by the script. You can find more information, and a working version of the Easy Firewall Generator at http://easyfwgen.morizot.net/.
在本章中,我们仔细研究了一些不同的图形用户界面以及其他用户界面可以做什么。请注意,市场上还有更多用户界面。本章主要让您了解市场上不同类型的防火墙管理界面。其中大多数都是开源的并且免费使用,而有些则需要花费一些钱才能获得全面的支持或功能。
In this chapter we have looked closer at what can be done with some different graphical user interfaces, and other user interfaces as well. Note that there are several more user interfaces around on the market. This chapter has mainly given you an idea of the different types of firewall administration interfaces around on the market. Most of them are open source and free to use, while some will cost a bit of money to get full support or functionality from.
添加此部分是为了让公司可以测试其产品并将其添加到本教程中。如果您是一家公司,并且希望在本节中测试和审查您的产品,我们非常欢迎您通过常规渠道与作者联系(请参阅本教程的顶部)。请注意,本部分并不是寻找产品测试的明确位置。相反,它是一种尝试,为所有基于 Linux 的产品的企业生产商以及为 GNU/Linux 软件的开发做出贡献的人提供一些东西。
This section was added so that corporations may have their products tested and added to this tutorial. If you are a company and would like to have your products tested and reviewed in this section, you are more than welcome to contact the author through usual channels (see the top of this tutorial). Mind you that this section is not the definite place to look for product testing. It is rather a try to offer something to all of the corporate producers of Linux based products, and who contribute to the development of GNU/Linux software.
如果有人觉得他们的产品在这里受到了不好的审查,我们非常欢迎他们联系作者以获得更完整的问题描述,或者让他们的修改后的产品可能用更新的固件重新审查等。这可能会改变,因为作者不知道这个评论部分会有多受欢迎。
If someone feels that their product has been badly reviewed here, they are more than welcome to contact the author for a more complete description of the problem, or to have their revised product possibly re-reviewed with newer firmwares etc. This might change, since the author doesn't know how popular this review section will be.
简而言之,InGate Firewall 1200是一款商业防火墙产品。老实说,它们绝对处于昂贵的范围内,不适合大多数/任何家庭用户。然而,一分钱一分货,换句话说,这是一款优秀的产品。在我们进一步讨论之前,应该指出的是,InGate 防火墙是硬件和软件解决方案。基本上它是一台非常小的计算机,运行修改后的 Linux 内核。当然,您几乎永远不会看到它实际上正在运行 Linux(除了界面中的命名约定等)。
In short, the InGate Firewall 1200 is a commercial firewall product. To be fairly honest, they are definitely in the pricey range and not for most/any home-users. However, you get what you pay for, and this is an excellent product in other words. Before we go any further, it should be noted that the InGate firewalls are hardware and software solutions. Basically it is a very small computer running a modified Linux kernel. Of course, you will pretty much never see that it is actually running Linux (except for naming conventions in the interface, and so forth).
我们投入了大量的精力来创建一个非常先进的 Web 界面来配置和管理防火墙。InGate 1200 防火墙有 2 个 10/100 Mbps 以太网连接器,较大的版本有更多(最多 6 个 10/100/1000 Mbps 以太网连接器和 2 个迷你 Gbic 端口)。
A lot of effort has been put into creating a nicely advanced webinterface to configure and administrate the firewall from. The InGate 1200 firewall has 2 10/100 Mbps Ethernet connectors and the larger versions has more (up to 6 10/100/1000 Mbps Ethernet connectors and 2 mini Gbic ports).
它们还具有SIP遍历支持和对互联网电话的SIP支持,并内置对TLS的支持。1200 附带 2 个 SIP 用户许可证,数量根据您购买的防火墙/SIParator 的不同而有所不同。用于处理SIP 的用户界面非常出色且非常直观,尽管它确实使用了大量技术术语。换句话说,保留本手册可能是个好主意,无论您在这台机器上做什么,实际上这可能都是正确的,原因有多种。该手册写得非常好,在您习惯他们选择使用的高科技语言之前,可能很难理解该界面。该手册有 250 多页,在撰写本文时有英语和瑞典语版本,正如我已经说过的,写得非常好。
They also have SIP traversal support and SIP support for Internet telephony, and built in support for TLS. The 1200 came with 2 SIP user licenses, and the number differs depending on which firewall/SIParator you buy. The user interface for handling SIP is excellent and very intuitive, though it does use quite a lot of tech heavy jargon. It might be a good idea to keep the manual around in other words, which might actually be true whatever you are doing on this machine, for multiple reasons really. The manual is excellently written, and it might also be very hard to understand the interface before you get used to the highly technical language they have chosen to use. The manual is 250+ pages and available both in English and Swedish as of this writing, and as I've already said, very well written.
除此之外,InGate防火墙还具有基于ipsec的 VPN 和 QoS 支持。基于ipsec的VPN 应该能够与所有其他ipsec实现互操作,包括“Road Warrior”漫游。
On top of this, the InGate firewalls has ipsec based VPN and QoS support. The ipsec based VPN should be interoperable with all other ipsec implementations, including "Road Warrior" roaming.
该设备还具有非常简单的设置日志记录功能。机器可以在本地登录,也可以通过系统日志和/或邮件登录。本地日志记录工具具有非常好的、细粒度的日志搜索能力。我对本地日志记录工具的唯一问题是搜索引擎可能有点太慢了。这实际上是我对整个防火墙主要也是唯一关心的,整个用户界面有点慢,有时编辑后会跳到主页。然而,这可能已在较新的版本中得到修复。考虑到所有因素,这根本不是一个严重的错误,而且它可能比缓慢的用户界面/奇怪的链接更糟糕。
The device also has a very simple to setup logging facility. The machine can either log locally, or via syslog and/or mail. The local logging facility has exceptionally good and finegrained search capabilities through the logs. My only problem with the local logging facility is that the search engine might be a little bit too slow. This is actually my main and only concern with the whole firewall, the whole user interface is a bit slow, and sometimes it jumps to the main page after editing. This might have been fixed in newer versions however. All things considered, this isn't a bad fault at all, and it could have been much worse than a slow user interface/weird linking.
当我第一次尝试我得到的测试机时,我非常糟糕地破坏了配置(即,我颠倒了接口等)。因此,我最初的设置时间大约为 4-5 小时才能访问互联网。如果我没有犯这些初始错误,最初的配置时间可能会在 1 小时左右。当然,只有在使用(对您而言)未知的新界面时,才会出现这种情况。
The first time I tried the test machine that I got, I borked the configuration pretty badly (I.e., I inverted the interfaces among other things). Because of this, my original setup time was around 4-5 hours before I could reach the Internet. If I hadn't done these initial errors, the original configuration time would probably have been around 1 hour or so. Of course, this can only be expected when using a new and unknown (to you) interface.
默认值非常好。换句话说,除了最基本的选项之外,它们是不存在的。您要做的第一件事是通过“magic ping”设置设备的 IP 地址(将设备 MAC 地址设置为 IP 地址,然后 ping 该 IP 地址 - 这必须在本地完成)。相对的以太网端口默认处于关闭状态,直到您将其打开,并且除了最基本的配置之外,没有任何配置由 InGate 开发人员完成(日志组等)。
The default values are very good. In other words, they are non-existant except for the most basic options. The first thing you do, is to set the IP address of the device via a "magic ping" (set the device mac address to an IP address and then ping the IP address - this must be done locally). The opposite ethernet port is per default turned off, until you turn it on, and no configuration except the most basic is done by the InGate developers (log groups and so on).
总之,这是我在市场上见过的最好的商业防火墙之一。唯一真正的缺陷是用户界面有点慢而且该设备价格相当高。该设备的优点远远超过任何公司都会遇到的大多数成本问题,并且不必从头安装自己的系统的简单性实际上可以使其成为比从头安装的系统更简单、更便宜的设备设置,对于大多数人来说公司 - 特别是当流程包含大量防火墙并且管理员在其他 InGate 产品方面经验丰富时。当然,我的假设总是如此!
In conclusion, this is one of the best commercial firewalls I have seen on the market. The only real flaw is that the user interface is a tad slow and that the device is rather high priced. The pros of the device far far outweighs most cost issues that any company would have, and the simplicity of not having to scratch install a system of your own could actually make this a simpler and cheaper device to set up than a scratch installed system for most companies - especially if the process consists of a large quantity of firewalls and the administrators are experienced in other InGate products. Of course, this is always the case I assume!
本章讨论了一些基于 iptables、netfilter 和 Linux 的不同商业防火墙产品。这个列表比你在本章中看到的要长得多。然而,为了让我尝试它们,我必须首先测试一些东西。如果您知道您认为我应该在本节中提供的产品,为什么不让我访问它几天,或者致电生产商,看看他们是否愿意向我发送样本/演示副本?
This chapter has discussed some different commercial firewalling products based on iptables, netfilter and linux. This list is much, much longer than what you have seen in this chapter. However, for me to try them out, I must have something to test to begin with. If you know of a product that you think I should have in this section, why not either give me access to it for a couple of days, or call the producer and see if they wouldn't like to send me a sample/demo copy?
嗯,这是最后一章了。剩下的只是不同的附录。其中一些包含一些相当有趣的信息,但不太适合任何特定章节,而另一些则只是通用表格,等等。如果您对该领域有进一步的兴趣,有大量的材料可供阅读,为什么不加入 netfilter 网站上提供的邮件列表呢?或者为什么不开始开发 iptables 和 netfilter 呢?我希望您喜欢阅读本文档,并且能够将其中的一些内容进行实际测试。
Well, this was the last chapter. What's left is just the different appendices. Some of them contains some rather interesting information that didn't quite fit into any specific chapter, and others are just generic tables, and so forth. If you have any further interest in the area, there is tons and tons of material to read, and why not join the mailinglists available at the netfilter website? Or why not start developing for iptables and netfilter? I hope you have enjoyed reading this document and that you have been able to set some of it to the real world test.
要列出当前活动的规则集,请运行 iptables 命令的特殊选项,我们之前在如何构建规则一章中对此进行了简要讨论。这看起来像下面这样:
To list your currently active rule-set you run a special option to the iptables command, which we have discussed briefly previously in the How a rule is built chapter. This would look like the following:
iptables-L
iptables -L
此命令应列出您当前活动的规则集,并将所有可能的内容转换为更易读的形式。例如,它会根据 /etc/services文件转换所有不同的端口以及 DNS 所有 IP 地址以获取 DNS 记录。但后者可能有点问题。例如,它会尝试将 LAN IP 地址(即 192.168.1.1)解析为有用的地址。192.168.0.0/16 是一个私有范围,不应解析为任何内容,并且该命令在解析 IP 时似乎会挂起。为了解决这个问题,我们会做如下的事情:
This command should list your currently active rule-set, and translate everything possible to a more readable form. For example, it will translate all the different ports according to the /etc/services file as well as DNS all the IP addresses to get DNS records instead. The latter can be a bit of a problem though. For example, it will try to resolve LAN IP addresses, i.e. 192.168.1.1, to something useful. 192.168.0.0/16 is a private range though and should not resolve to anything and the command will seem to hang while resolving the IP. To get around this problem we would do something like the following:
iptables-L-n
iptables -L -n
另一件可能有趣的事情是查看有关每个政策、规则和链的一些统计数据。我们可以通过添加详细标志来实现这一点。然后它看起来像这样:
Another thing that might be interesting is to see a few statistics about each policy, rule and chain. We could get this by adding the verbose flag. It would then look something like this:
iptables -L -n -v
iptables -L -n -v
不要忘记还可以列出 nat 和 mangle 表。这是通过 -t 开关完成的,如下所示:
Don't forget that it is also possible to list the nat and mangle tables. This is done with the -t switch, like this:
iptables -L -t nat
iptables -L -t nat
/proc文件系统中还有一些可能值得查看的文件 。例如,了解 conntrack 表中当前有哪些连接可能很有趣。该表包含当前跟踪的所有不同连接,并作为基本表,因此我们始终知道连接当前处于什么状态。该表无法编辑,即使可以编辑,这也是一个坏主意。要查看该表,您可以运行以下命令:
There are also a few files that might be interesting to look at in the /proc file system. For example, it might be interesting to know what connections are currently in the conntrack table. This table contains all the different connections currently tracked and serves as a basic table so we always know what state a connection currently is in. This table can't be edited and even if it was possible, it would be a bad idea. To see the table you can run the following command:
猫 /proc/net/ip_conntrack | 较少的
cat /proc/net/ip_conntrack | less
上面的命令将显示所有当前跟踪的连接,尽管可能有点难以理解所有内容。
The above command will show all currently tracked connections even though it might be a bit hard to understand everything.
如果在某个时候你搞砸了你的 iptables,实际上有命令可以刷新它们,所以你不必重新启动。实际上我已经被问过几次这个问题了,所以我想我应该在这里回答它。如果您错误添加了规则,您只需将错误添加的行中的 -A 参数更改为 -D 即可。iptables 会找到错误的行并为您删除它,如果您有多行在链中看起来完全相同,它会删除它找到的与您的规则匹配的第一个实例。如果这不是想要的行为,您可以尝试使用 -D 选项作为 iptables -D INPUT 10 ,这将删除 INPUT 链中的第 10 条规则。
If at some point you screw up your iptables, there are actually commands to flush them, so you don't have to reboot. I've actually gotten this question a couple times by now so I thought I'd answer it right here. If you added a rule in error, you might just change the -A parameter to -D in the line you added in error. iptables will find the erroneous line and erase it for you, in case you've got multiple lines looking exactly the same in the chain, it erases the first instance it finds matching your rule. If this is not the wanted behavior you might try to use the -D option as iptables -D INPUT 10 which will erase the 10th rule in the INPUT chain.
还有一些情况您想要刷新整个链,在这种情况下您可能需要运行 -F 选项。例如, iptables -F INPUT 将擦除整个 INPUT 链,但这不会更改默认策略,因此如果将其设置为 DROP,如果按上述方式使用,您将阻止整个 INPUT 链。要重置链策略,请按照您的操作将其设置为 DROP,例如 iptables -P INPUT ACCEPT。
There are also instances where you want to flush a whole chain, in this case you might want to run the -F option. For example, iptables -F INPUT will erase the whole INPUT chain, though, this will not change the default policy, so if this is set to DROP you'll block the whole INPUT chain if used as above. To reset the chain policy, do as you did to set it to DROP, for example iptables -P INPUT ACCEPT.
我制作了一个rc.flush-iptables.txt(也可以作为附录提供),它将刷新并重置您的 iptables,您在正确设置rc.firewall.txt文件时可能会考虑使用它。但有一件事;如果你开始在 mangle 表中乱搞,这个脚本不会删除它们,添加删除它们所需的几行相当简单,但我没有在这里添加它们,因为我的 rc.firewall 中没有使用 mangle 表 。 txt脚本到目前为止。
I have made a rc.flush-iptables.txt (available as an appendix as well) that will flush and reset your iptables that you might consider using while setting up your rc.firewall.txt file properly. One thing though; if you start mucking around in the mangle table, this script will not erase those, it is rather simple to add the few lines needed to erase those but I have not added those here since the mangle table is not used in my rc.firewall.txt script so far.
加载模块时您可能会遇到一些问题。例如,您可能会收到错误消息,声称不存在具有此名称的模块等等。例如,这可能如下所示。
You may run into a few problems with loading modules. For example, you could get errors claiming that there is no module by such a name and so on. This may, for example look like the following.
insmod: iptable_filter: 未找到该名称的模块
insmod: iptable_filter: no module by that name found
目前还没有理由担心。这个或这些模块可能已静态编译到您的内核中。这是在尝试解决此问题时首先应该考虑的事情。查看这些模块是否已加载或者是否已静态编译到内核中的最简单方法是尝试运行使用特定功能的命令。在上述情况下,我们无法加载过滤表。如果没有这个功能,我们就根本无法使用过滤表。要检查过滤器表是否存在,我们执行以下操作。
This is no reason for concern yet. This or these modules may possibly have been statically compiled into your kernel. This is the first thing you should look at when trying to solve this problem. The simplest way to see if these modules have been loaded already or if they are statically compiled into the kernel, is to simply try and run a command that uses the specific functionality. In the above case, we could not load the filter table. If this functionality is not there, we should be unable to use the filter table at all. To check if the filter table is there, we do the following.
iptables -t 过滤器 -L
iptables -t filter -L
这应该正确输出过滤表中的所有链,否则就会失败。如果一切正常,那么它应该看起来像这样,具体取决于您是否插入了规则。
This should either output all of the chains in the filter table properly, or it should fail. If everything is o.k., then it should look something like this depending on if you have rules inserted or not.
链输入(策略接受)
目标 prot 选择源目的地
链转发(策略接受)
目标 prot 选择源目的地
链输出(策略接受)
目标 prot 选择源目的地
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
如果您没有加载过滤器表,您将收到如下所示的错误。
If you do not have the filter table loaded, you would get an error that looks something like this instead.
iptables v1.2.5:无法初始化 iptables 表“过滤器”:表 \
不存在(需要insmod吗?)
也许 iptables 或您的内核需要升级。
iptables v1.2.5: can't initialize iptables table `filter': Table \
does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
这有点严重,因为它首先指出我们没有将功能编译到内核中,其次,在我们的正常模块路径中不可能找到该模块。这可能意味着您忘记安装模块,忘记运行 depmod -a 来更新模块数据库,或者您没有将功能编译为模块或静态到内核中。当然可能还有其他原因导致模块无法加载,但这些是主要原因。大多数这些问题都很容易解决。第一个问题只需在内核源代码目录中运行 make module_install 即可解决(如果源代码已编译且模块已构建)。第二个问题只需运行一次 depmod -a 并查看之后是否有效即可解决。第三个问题对于这个解释来说有点不合时宜,在这里你或多或少只能靠自己的智慧了。您很可能会在以下位置找到更多相关信息:Linux 文档项目主页。
This is a bit more serious since it points out that we, first of all, do not have the functionality compiled into the kernel, and second, that the module is not possible to find in our normal module paths. This may either mean that you have forgotten to install your modules, you have forgotten to run depmod -a to update your module databases, or you have not compiled the functionality as either module or statically into the kernel. There may of course be other reasons for the module not to be loaded, but these are the main reasons. Most of these problems are easily solved. The first problem would simply be solved by running make modules_install in the kernel source directory (if the source has already been compiled and the modules have already been built). The second problem is solved by simply running depmod -a once and see if it works afterward. The third problem is a bit out of the league for this explanation, and you are more or less left to your own wits here. You will most probably find more information about this on the Linux Documentation Project homepage.
运行 iptables 时可能遇到的另一个错误是以下错误。
Another error that you may get when running iptables is the following error.
iptables:没有该名称的链/目标/匹配
iptables: No chain/target/match by that name
这个错误告诉我们不存在这样的链、目标或匹配。这可能取决于一系列因素,最常见的是您拼错了相关链、目标或匹配项。另外,如果您尝试使用不可用的匹配项,则可能会生成此错误,因为您没有加载正确的模块,它没有编译到内核中,或者 iptables 无法自动加载模块。一般来说,您应该查找上述所有解决方案,但也要查找规则中某种拼写错误的目标。
This error tells us that there is no such chain, target or match. This could depend upon a huge set of factors, the most common being that you have misspelled the chain, target or match in question. Also, this could be generated in case you are trying to use a match that is not available, either because you did not load the proper module, it was not compiled into the kernel, or iptables failed to automatically load the module. In general, you should look for all of the above solutions but also look for misspelled targets of some sort or another in your rule.
有一定的特点在 iptables 中,这一点没有很好的记录,因此可能被很多人(是的,包括我)忽视。如果您使用状态 NEW,未设置 SYN 位的数据包将通过您的防火墙。之所以存在此功能,是因为在某些情况下,我们希望考虑数据包可能是另一个防火墙上已建立的连接的一部分。此功能使得可以拥有两个或多个防火墙,并且其中一个防火墙关闭时不会丢失任何数据。然后子网的防火墙可以由我们的辅助防火墙接管。然而,这确实导致这样一个事实:状态 NEW 将允许几乎任何类型的 TCP 连接,无论这是否是初始的 3 次握手。为了解决这个问题,我们将以下规则添加到防火墙的 INPUT、OUTPUT 和 FORWARD 链中:
There is a certain feature in iptables that is not so well documented and may therefore be overlooked by a lot of people (yes, including me). If you use state NEW, packets with the SYN bit unset will get through your firewall. This feature is there because in certain cases we want to consider that a packet may be part of an already ESTABLISHED connection on, for instance, another firewall. This feature makes it possible to have two or more firewalls, and for one of the firewalls to go down without any loss of data. The firewalling of the subnet could then be taken over by our secondary firewall. This does however lead to the fact that state NEW will allow pretty much any kind of TCP connection, regardless if this is the initial 3-way handshake or not. To take care of this problem we add the following rules to our firewalls INPUT, OUTPUT and FORWARD chain:
$IPTABLES -A 输入 -p tcp !--syn -m 状态 --state 新-j 日志 \
--log-prefix "新的不是 syn:"
$IPTABLES -A 输入 -p tcp !--syn -m 状态 --state 新-j 删除
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
上述规则将解决这个问题。这是 Netfilter/iptables 项目的一个记录不良的行为,绝对应该更加突出。换句话说,对于这种行为,防火墙上会发出一个巨大的警告。 The above rules will take care of this problem. This is a badly documented behavior of the Netfilter/iptables project and should definitely be more highlighted. In other words, a huge warning is in its place for this kind of behavior on your firewall. |
请注意,上述规则存在一些问题,而且 Microsoft TCP/IP 实现也很糟糕。上述规则将导致某些情况,其中 Microsoft 产品生成的数据包被标记为状态 NEW,因此被记录并丢弃。然而,这不会导致与我的知识的联系中断。当连接关闭、发送最终的 FIN/ACK、Netfilter 的状态机关闭连接并且它不再位于 conntrack 表中时,就会出现问题。此时,错误的 Microsoft 实现发送了另一个数据包,该数据包被视为状态 NEW,但缺少 SYN 位,因此与上述规则匹配。换句话说,不要太担心这个规则,或者如果你还是担心的话,
Note that there are some troubles with the above rules and bad Microsoft TCP/IP implementations. The above rules will lead to certain conditions where packets generated by Microsoft product gets labeled as state NEW and hence get logged and dropped. It will however not lead to broken connections to my knowledge. The problem occurs when a connection gets closed, the final FIN/ACK is sent, the state machine of Netfilter closes the connection and it is no longer in the conntrack table. At this point the faulty Microsoft implementation sends another packet which is considered as state NEW but lacks the SYN bit and hence gets matched by the above rules. In other words, don't worry to much about this rule, or if you are worried anyways, set the --log-headers option to the rule and log the headers too and you'll get a better look at what the packet looks like.
这些规则还有一个众所周知的问题。如果某人当前连接到防火墙(假设从 LAN),并且您已将脚本设置为在运行 PPP 连接时激活。这样的话,当你启动PPP连接时,之前通过局域网连接的人或多或少都会被杀掉。这只适用于当您使用 conntrack 和 nat 代码库作为模块运行时,并且每次运行脚本时都会加载和卸载模块。解决此问题的另一种方法是运行rc.firewall.txt来自主机(不在实际防火墙上)的 telnet 连接的脚本。简而言之,您可以使用 telnet 或其他一些流连接进行连接。启动连接跟踪模块,然后加载新的非 SYN 数据包规则。最后,telnet 客户端或守护程序尝试发送一些内容。连接跟踪代码不会将此连接识别为合法连接,因为它之前没有看到此连接上任何方向的数据包,而且也不会设置 SYN 位,因为它实际上不是连接中的第一个数据包。因此,数据包将符合规则并被记录,然后被丢弃到地面。
There is one more known problem with these rules. If someone is currently connected to the firewall, let's say from the LAN, and you have the script set to be activated when running a PPP connection. In this case, when you start the PPP connection, the person previously connected through the LAN will be more or less killed. This only applies when you are running with the conntrack and nat code bases as modules, and the modules are loaded and unloaded each time you run the script. Another way to get this problem is to run the rc.firewall.txt script from a telnet connection from a host not on the actual firewall. To put it simply, you connect with telnet or some other stream connection. Start the connection tracking modules, then load the NEW not SYN packet rules. Finally, the telnet client or daemon tries to send something. the connection tracking code will not recognize this connection as a legal connection since it has not seen packets in any direction on this connection before, also there will be no SYN bits set since it is not actually the first packet in the connection. Hence, the packet will match to the rules and be logged and after-wards dropped to the ground.
某些 TCP 欺骗攻击使用一种称为序列号预测的技术。在这种类型的攻击中,攻击者在攻击某人的同时欺骗其他一些主机的 IP 地址,并尝试预测该主机使用的序列号。
Certain TCP spoofing attacks uses a technique called Sequence Number Prediction. In this type of attack, the attacker spoofs some other hosts IP address, while attacking someone, and tries to predict the Sequence number used by that host.
让我们看看通过序列号预测进行的典型 TCP 欺骗。玩家:“攻击者”[A],尝试将数据包发送给“受害者”[V],假装是某个“其他主机”[O]。
Let's look on typical TCP spoofing by sequence number prediction. Players: "attacker" [A], trying to send packets to a "victim" [V], pretending to be some "other host" [O].
[A] 向 [V] 发送 SYN,源 IP 为 [O]。
[A] sends SYN to [V] with source IP of [O].
[V] 通过 SYN/ACK 回复 [O]。
[V] replies to [O] by SYN/ACK.
现在 [O] 应该通过 RST 回复未知的 SYN/ACK,并且攻击不成功,但我们假设 [O] 已关闭(被淹没、关闭或位于已丢弃数据包的防火墙后面)。
now [O] should reply to an unknown SYN/ACK by RST and the attack is unsuccesful, but let's assume [O] is down (flooded, turned off or behind firewall that has dropped the packets).
如果 [O] 没有搞砸,[A] 现在可以与假装是 [O] 的 [V] 交谈,只要它预测了正确的序列号。
if [O] didn't mess it up, [A] now can talk to [V] pretending to be [O] as long as it predicts correct sequence numbers.
只要我们不在步骤3中向未知的SYN/ACK发送RST数据包,我们就会让[V]受到攻击,而我们自己也会受到连累。因此,一般礼貌是以适当的方式将 RST 发送给 [V]。如果我们使用规则集中指定的 NEW 而非 SYN 规则,SYN/ACK 数据包将被丢弃。因此,我们在 bad_tcp_packets 链中有以下规则,位于 NEW not SYN 规则之上:
As long as we do not send the RST packet to the unknown SYN/ACK in step 3, we will allow [V] to be attacked, and ourselves to be incriminated. Common courtesy, would hence be to send the RST to [V] in a proper way. If we use the NEW not SYN rules specified in the ruleset, SYN/ACK packets will be dropped. Hence, we have the following rules in the bad_tcp_packets chain, just above the NEW not SYN rules:
iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \ -m 状态 --state NEW -j REJECT --reject-with tcp-reset
iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \ -m state --state NEW -j REJECT --reject-with tcp-reset
在这种情况下成为 [O] 的机会应该相对较小,但这些规则在几乎所有情况下都应该是安全的。除非您运行多个冗余防火墙,这些防火墙通常会相互接管数据包或流。在这种情况下,某些连接可能会被阻止,即使它们是合法的。该规则实际上也可能允许一些端口扫描也可以看到我们的防火墙,但他们不应该能够透露更多信息。
The chance of being [O] in this scenario should be relatively small, but these rules should be safe in almost all cases. Except when you run several redundant firewalls which will often take over packets or streams from each other. In such case, some connections may be blocked, even though they are legit. This rule may actually also allow a few portscans to see our firewall as well, but they should not be able to tell much more than that.
自从我的一个朋友告诉我一些我完全忘记的事情以来,我就添加了这一点。某些愚蠢的互联网服务提供商使用IANA分配的 IP 地址用于您连接到的本地网络。例如,瑞典互联网服务提供商和电话垄断企业 Telia 在其 DNS 服务器上使用这种方法,该服务器使用 10.xxx IP 地址范围。编写脚本时可能遇到的一个常见问题是,您不允许 10.xxx 范围内的任何 IP 地址与您自己建立连接,因为存在欺骗的可能性。嗯,不幸的是,这里有一个例子,您实际上可能需要稍微放松一下这些规则。您可以在欺骗部分上方插入一条 ACCEPT 规则,以允许来自这些 DNS 服务器的流量,或者您可以注释掉脚本的该部分。它可能是这样的:
I have added this since a friend of mine told me something I have totally forgotten. Certain stupid Internet Service Providers use IP addresses assigned by IANA for their local networks on which you connect to. For example, the Swedish Internet Service Provider and phone monopoly Telia uses this approach for example on their DNS servers, which uses the 10.x.x.x IP address range. A common problem that you may run into when writing your scripts, is that you do not allow connections from any IP addresses in the 10.x.x.x range to yourself, because of spoofing possibilities. Well, here is unfortunately an example where you actually might have to lift a bit on those rules. You might just insert an ACCEPT rule above the spoof section to allow traffic from those DNS servers, or you could just comment out that part of the script. This is how it might look:
/usr/local/sbin/iptables -t nat -I PREROUTING -i eth1 -s \
10.0.0.1/32 -j 接受
/usr/local/sbin/iptables -t nat -I PREROUTING -i eth1 -s \
10.0.0.1/32 -j ACCEPT
我想花点时间抱怨一下这些互联网服务提供商。这些 IP 地址范围不是分配给您用于此类愚蠢的事情的,至少据我所知不是这样。对于大型公司网站来说,或者您自己的家庭网络是可以的,但是您不应该仅仅因为您的一些突发奇想就强迫我们开放自己。你们是大型互联网提供商,如果你们无力为 DNS 服务器购买 3-4 个 IP 地址,我就很难信任你们。
I would like to take my moment to bitch at these Internet Service Providers. These IP address ranges are not assigned for you to use for dumb stuff like this, at least not to my knowledge. For large corporate sites it is more than o.k., or your own home network, but you are not supposed to force us to open up ourselves just because of some whim of yours. You are large Internet providers, and if you can't afford buying some 3-4 IP addresses for your DNS servers, I have a very hard time trusting you.
这实际上是一个相当简单的任务,但是,一旦您了解了 DHCP 的工作原理,您就必须对允许哪些内容和不允许哪些内容保持谨慎。首先,我们应该知道 DHCP 的工作原理通过UDP协议。因此,这是首先要寻找的事情。其次,我们应该检查我们从哪个接口获取和发送请求。例如,如果我们的 eth0 接口设置了 DHCP,则我们不应允许 eth1 上的 DHCP 请求。为了使规则更加具体,我们只允许 DHCP 使用的实际 UDP 端口,即端口 67 和 68。这些是我们选择匹配数据包的标准,也是我们允许的。该规则现在如下所示:
This is a fairly simple task really, once you get to know how DHCP works, however, you must be a little bit cautious with what you do let in and what you do not let in. First of all, we should know that DHCP works over the UDP protocol. Hence, this is the first thing to look for. Second, we should check which interface we get and send the request from. For example, if our eth0 interface is set up with DHCP, we should not allow DHCP requests on eth1. To make the rule a bit more specific, we only allow the actual UDP ports used by DHCP, which should be ports 67 and 68. These are the criteria that we choose to match packets on, and that we allow. The rule would now look like this:
$IPTABLES -I 输入 -i $LAN_IFACE -p udp --dport 67:68 --sport \
67:68 -j 接受
$IPTABLES -I INPUT -i $LAN_IFACE -p udp --dport 67:68 --sport \
67:68 -j ACCEPT
请注意,我们现在允许进出 UDP 端口 67 和 68 的所有流量,但是,这不应该是一个大问题,因为它只允许来自从端口 67 或 68 进行连接的主机的请求。当然,该规则可能更具限制性,但它应该足以实际接受所有 DHCP 请求和更新,而不会造成太大的漏洞。如果您担心的话,这条规则当然可以变得更加严格。
Do note that we allow all traffic to and from UDP port 67 and 68 now, however, this should not be such a huge problem since it only allows requests from hosts doing the connection from port 67 or 68 as well. This rule could, of course, be even more restrictive, but it should be enough to actually accept all DHCP requests and updates without opening up too large of holes. If you are concerned, this rule could of course be made even more restrictive.
mIRC 使用特殊设置,允许其穿过防火墙进行连接,并使 DCC 连接在防火墙不知情的情况下正常工作。如果此选项与 iptables 特别是 ip_conntrack_irc 和 ip_nat_irc 模块一起使用,它将根本不起作用。问题是 mIRC 会自动为您对数据包内部进行 NAT,当数据包到达防火墙时,防火墙根本不知道如何处理它以及如何处理它。mIRC 并不期望防火墙足够智能,能够通过简单地查询 IRC 服务器的 IP 地址并使用该地址发送 DCC 请求来自行处理此问题。
mIRC uses a special setting which allows it to connect through a firewall and to make DCC connections work properly without the firewall knowing about it. If this option is used together with iptables and specifically the ip_conntrack_irc and ip_nat_irc modules, it will simply not work. The problem is that mIRC will automatically NAT the inside of the packets for you, and when the packet reaches the firewall, the firewall will simply not know how and what to do with it. mIRC does not expect the firewall to be smart enough to take care of this by itself by simply querying the IRC server for its IP address and sending DCC requests with that address instead.
打开“我位于防火墙后面”配置选项并使用 ip_conntrack_irc 和 ip_nat_irc 模块将导致 Netfilter 创建包含以下内容“伪造的 DCC 发送数据包”的日志条目。
Turning on the "I am behind a firewall" configuration option and using the ip_conntrack_irc and ip_nat_irc modules will result in Netfilter creating log entries with the following content "Forged DCC send packet".
最简单的解决方案是取消选中 mIRC 中的配置选项并让 iptables 完成工作。这意味着,您应该明确告诉 mIRC 它不在防火墙后面。
The simplest possible solution is to just uncheck that configuration option in mIRC and let iptables do the work. This means, that you should tell mIRC specifically that it is not behind a firewall.
这是所有 ICMP 类型的完整列表。请注意指向 RFC 的参考或介绍类型和代码的人员。有关所有 ICMP 类型和代码的完整且绝对最新的列表,请参阅Internet 号码分配机构中的icmp 参数 文档。
This is a complete listing of all ICMP types. Note the reference pointing to the RFC or person who introduced the type and code. For a complete and absolute up to date listing of all ICMP types and codes, look at the icmp-parameters document at Internet Assigned Numbers Authority.
Iptables 和 netfilter 在内部使用 ICMP 类型 255,因为它不保留用于任何实际用途,并且很可能永远不会有任何实际用途。如果您设置规则来匹配 iptables -A INPUT -p icmp --icmp-type 255 -j DROP,这将丢弃所有 ICMP 数据包。换句话说,它用于匹配所有 ICMP 类型。 Iptables and netfilter uses ICMP type 255 internally since it is not reserved for any real usage, and most likely will never have any real usage. If you set a rule to match iptables -A INPUT -p icmp --icmp-type 255 -j DROP, this will DROP all ICMP packets. It is in other words used to match all ICMP types. |
表 C-1。ICMP 类型
Table C-1. ICMP types
| 类型 | 代码 | 描述 | 询问 | 错误 | 参考 |
|---|---|---|---|---|---|
| 0 | 0 | 回声回复 | X | RFC792 | |
| 3 | 0 | 网络不可达 | X | RFC792 | |
| 3 | 1 | 主机无法访问 | X | RFC792 | |
| 3 | 2 | 协议不可达 | X | RFC792 | |
| 3 | 3 | 端口不可达 | X | RFC792 | |
| 3 | 4 | 需要碎片但没有碎片。位设置 | X | RFC792 | |
| 3 | 5 | 源路由失败 | X | RFC792 | |
| 3 | 6 | 目标网络未知 | X | RFC792 | |
| 3 | 7 | 目标主机未知 | X | RFC792 | |
| 3 | 8 | 源主机已隔离(已过时) | X | RFC792 | |
| 3 | 9 | 目的地网络受到行政禁止 | X | RFC792 | |
| 3 | 10 | 目标主机被行政禁止 | X | RFC792 | |
| 3 | 11 | TOS 无法访问网络 | X | RFC792 | |
| 3 | 12 | 根据 TOS 无法访问主机 | X | RFC792 | |
| 3 | 13 | 通过过滤行政禁止通信 | X | RFC1812 | |
| 3 | 14 | 主机优先级冲突 | X | RFC1812 | |
| 3 | 15 | 优先级截止生效 | X | RFC1812 | |
| 4 | 0 | 源淬灭 | RFC792 | ||
| 5 | 0 | 网络重定向 | RFC792 | ||
| 5 | 1 | 重定向到主机 | |||
| 5 | 2 | TOS 和网络重定向 | RFC792 | ||
| 5 | 3 | TOS 和主机重定向 | RFC792 | ||
| 8 | 0 | 回显请求 | X | RFC792 | |
| 9 | 0 | 路由器通告 - 普通路由器通告 | RFC1256 | ||
| 9 | 16 | 路由器通告 - 不路由普通流量 | RFC2002 | ||
| 10 | 0 | 路线选择 | RFC1256 | ||
| 11 | 0 | 传输期间 TTL 等于 0 | X | RFC792 | |
| 11 | 1 | 重组期间 TTL 等于 0 | X | RFC792 | |
| 12 | 0 | IP 标头错误(包罗万象的错误) | X | RFC792 | |
| 12 | 1 | 缺少必需的选项 | X | RFC1108 | |
| 12 | 2 | IP 标头长度错误 | X | RFC792 | |
| 13 | 0 | 时间戳请求(已过时) | X | RFC792 | |
| 14 | 时间戳回复(已废弃) | X | RFC792 | ||
| 15 | 0 | 信息请求(已废弃) | X | RFC792 | |
| 16 | 0 | 信息回复(已废弃) | X | RFC792 | |
| 17 号 | 0 | 地址掩码请求 | X | RFC950 | |
| 18 | 0 | 地址掩码回复 | X | RFC950 | |
| 20-29日 | 保留用于鲁棒性实验 | 苏兆星 | |||
| 30 | 0 | 路由追踪 | X | RFC1393 | |
| 31 | 0 | 数据报转换错误 | X | RFC1475 | |
| 32 | 0 | 移动主机重定向 | 大卫·约翰逊 | ||
| 33 | 0 | IPv6 你在哪里 | X | 比尔·辛普森 | |
| 34 | 0 | IPv6 我在这里 | X | 比尔·辛普森 | |
| 35 | 0 | 手机注册请求 | X | 比尔·辛普森 | |
| 36 | 0 | 手机注册回复 | X | 比尔·辛普森 | |
| 39 | 0 | 跳过 | 汤姆·马克森 | ||
| 40 | 0 | 萤火虫属 | RFC2521 |
本附录是官方认可的所有 TCP 选项的简单列表。这些参考文献和号码均取自互联网号码分配机构网站。可以在此位置找到主文件 。本文档中引用的人员的完整联系方式已被删除,因此有望减少他们的工作量。
This appendix is a simple and brief list of all the TCP options that are officially recognized. These references and numbers were all retreived from the Internet Assigned Numbers Authority website. The master file can be found at this location. The full contact details of the people referenced in this document has been removed, so to create less workload for them hopefully.
表 D-1。TCP 选项
Table D-1. TCP Options
| 复制 | 班级 | 数字 | 价值 | 姓名 | 参考 |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | EOOL - 选项列表结束 | [RFC791,JBP] |
| 0 | 0 | 1 | 1 | NOP-- 无操作 | [RFC791,JBP] |
| 1 | 0 | 2 | 130 | 美国证券交易委员会 - 安全 | [RFC1108] |
| 1 | 0 | 3 | 131 | LSR - 松散源路由 | [RFC791,JBP] |
| 0 | 2 | 4 | 68 | TS - 时间戳 | [RFC791,JBP] |
| 1 | 0 | 5 | 133 | E-SEC - 扩展安全性 | [RFC1108] |
| 1 | 0 | 6 | 134 | CIPSO - 商业安全 | [???] |
| 0 | 0 | 7 | 7 | RR - 记录路线 | [RFC791,JBP] |
| 1 | 0 | 8 | 136 | SID-流ID | [RFC791,JBP] |
| 1 | 0 | 9 | 137 | SSR - 严格源路由 | [RFC791,JBP] |
| 0 | 0 | 10 | 10 | ZSU - 实验测量 | [Z苏] |
| 0 | 0 | 11 | 11 | MTUP - MTU 探头 | [RFC1191]* |
| 0 | 0 | 12 | 12 | MTUR - MTU 回复 | [RFC1191]* |
| 1 | 2 | 13 | 205 | FINN - 实验流量控制 | [芬恩] |
| 1 | 0 | 14 | 142 | VISA - 实验访问控制 | [雌激素] |
| 0 | 0 | 15 | 15 | 编码-??? | [维斯蒂格] |
| 1 | 0 | 16 | 144 | IMITD - IMI 流量描述符 | [李] |
| 1 | 0 | 17 号 | 145 | EIP - 扩展互联网协议 | [RFC1385] |
| 0 | 2 | 18 | 82 | TR-路由追踪 | [RFC1393] |
| 1 | 0 | 19 | 147 | ADDEXT - 地址扩展 | [乌尔曼 IPv7] |
| 1 | 0 | 20 | 148 | RTRALT - 路由器警报 | [RFC2113] |
| 1 | 0 | 21 | 149 | SDB - 选择性定向广播 | [格拉夫] |
| 1 | 0 | 22 | 150 | NSAP - NSAP 地址 | [木匠] |
| 1 | 0 | 23 | 151 | DPS - 动态数据包状态 | [马里斯] |
| 1 | 0 | 24 | 152 | UMP - 上行组播包。 | [法里纳奇] |
以下是资源链接列表以及我从中获取信息等的链接:
Here is a list of links to resources and where I have gotten information from, etc :
ip-sysctl.txt - 来自 2.4.14 内核。虽然有点短,但对于 IP 网络控制及其对内核的作用是一个很好的参考。
ip-sysctl.txt - from the 2.4.14 kernel. A little bit short but a good reference for the IP networking controls and what they do to the kernel.
InGate - InGate 是一家商业防火墙生产商,使用 Linux 作为其防火墙产品的基础。他们的产品范围从基本防火墙到 SIP 网关和 QoS 机器。
InGate - InGate is a commercial firewall producer that uses Linux as the base for their firewall products. Their productrange goes from basic firewalls to SIP gateways and QoS machines.
RFC 768 - 用户数据报协议- 这是官方 RFC,详细描述了如何使用 UDP 协议及其所有标头。
RFC 768 - User Datagram Protocol - This is the official RFC describing how the UDP protocol should be used, in detail, and all of it's headers.
RFC 791 - 互联网协议- 互联网上仍在使用的 IP 规范,有补充和更新。IPv4 的基本原理仍然相同。
RFC 791 - Internet Protocol - The IP specification as still used on the Internet, with additions and updates. The basic is still the same for IPv4.
RFC 792 - Internet 控制消息协议- 有关 ICMP 数据包的所有信息的权威资源。无论您需要有关 ICMP 协议的技术信息,您都应该首先查阅这里。由 J. Postel 撰写。
RFC 792 - Internet Control Message Protocol - The definitive resource for all information about ICMP packets. Whatever technical information you need about the ICMP protocol, this is where you should turn first. Written by J. Postel.
RFC 793 - 传输控制协议- 这是有关 TCP 在所有主机上应如何运行的原始资源。自 1981 年以来,本文档一直是 TCP 如何工作的标准。技术性很强,但对于任何想要详细了解 TCP 的人来说都是必读的。这最初是由 J. Postel 编写的国防部标准。
RFC 793 - Transmission Control Protocol - This is the original resource on how TCP should behave on all hosts. This document has been the standard on how TCP should work since 1981 and forward. Extremely technical, but a must read for anyone who wants to learn TCP in every detail. This was originally a Department of Defense standard written by J. Postel.
RFC 1122 - 互联网主机的要求 - 通信层- 该 RFC 定义了在互联网主机上运行的软件的要求,特别是通信层。
RFC 1122 - Requirements for Internet Hosts - Communication Layers - This RFC defines the requirements of the software running on a Internet host, specifically the communication layers.
RFC 1349 - Internet 协议簇中的服务类型- RFC 描述了 IP 标头中 TOS 字段的一些更改和澄清。
RFC 1349 - Type of Service in the Internet Protocol Suite - RFC describing some changes and clarifications of the TOS field in the IP header.
RFC 1812 - IP 版本 4 路由器的要求- 该 RFC 指定 Internet 上的路由器应如何运行以及它们应如何处理不同的情况。非常有趣的阅读。
RFC 1812 - Requirements for IP Version 4 Routers - This RFC specifies how routers on the Internet should behave and how they are expected to handle different situations. Very interesting reading.
RFC 2401 - 互联网协议的安全架构- 这是一个讨论 IPSEC 实施和标准化的 RFC。如果您正在使用 IPSEC,那么非常值得一读。
RFC 2401 - Security Architecture for the Internet Protocol - This is an RFC talking about the IPSEC implementation and standardisation. Well worth reading if you are working with IPSEC.
RFC 2474 - IPv4 和 IPv6 标头中区分服务字段(DS 字段)的定义- 在本文档中,您将了解 DiffServ 的工作原理,并且您将找到有关 TCP/IP 协议添加/更改所需的大量信息。 DiffServ 协议才能工作。
RFC 2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers - In this document you will find out how the DiffServ works, and you will find much needed information about the TCP/IP protocol additions/changes needed for the DiffServ protocol to work.
RFC 2638 - 用于互联网的两位差分服务架构- 该 RFC 描述了一种将两种不同的差分服务架构实现为一个的方法。两者最初都是由 D. Clark 和 van Jacobsen 在 1997 年慕尼黑 IETH 会议上描述的。
RFC 2638 - A Two-bit Differentiated Services Architecture for the Internet - This RFC describes a method of implementing two different differentiated service architecture into one. Both where described originally by D. Clark and van Jacobsen at the Munich IETH meeting 1997.
RFC 2960 - 流控制传输协议- 这是由几家大型电信公司开发的相对较新的协议,用于补充 UDP 和 TCP 作为具有更高可靠性和弹性的第 3 层协议。
RFC 2960 - Stream Control Transmission Protocol - This is a relatively new protocol developed by several large telecoms companies to complement UDP and TCP as a layer 3 protocol with higher reliability and resilience.
RFC 3168 - 在 IP 中添加显式拥塞通知 (ECN) - 该 RFC 定义了如何在技术层面上使用 ECN 以及如何在 TCP 和 IP 协议中实现它。由 K. Ramakrishnan、S. Floyd 和 D. Black 撰写。
RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP - This RFC defines how ECN is to be used on a technical level and how it should be implemented in the TCP and IP protocols. Written by K. Ramakrishnan, S. Floyd and D. Black.
RFC 3260 - Diffserv 的新术语和说明- 本备忘录记录了 Diffserv 工作组关于新术语和改进术语的协议,并提供了次要的技术说明。
RFC 3260 - New Terminology and Clarifications for Diffserv - This memo captures Diffserv working group agreements concerning new and improved terminology, and provides minor technical clarifications.
RFC 3286 - 流控制传输协议简介- RFC 介绍流控制传输协议,这是 TCP/IP 堆栈中相对较新的第 3 层协议。由几家大型电信公司开发。
RFC 3286 - An Introduction to the Stream Control Transmission Protocol - RFC introducing the Stream Control Transmission Protocol, a relatively new layer 3 protocol in the TCP/IP stack. Developed by several large telecom companies.
ip_dynaddr.txt - 来自 2.4.14 内核。对通过 sysctl 和 proc 文件系统可用的 ip_dynaddr 设置的非常简短的参考。
ip_dynaddr.txt - from the 2.4.14 kernel. A really short reference to the ip_dynaddr settings available via sysctl and the proc file system.
iptables.8 - iptables 1.3.1 手册页。这是手册页的 HTML 版本,是阅读/编写 iptables 规则集时的绝佳参考。始终将其放在手边。
iptables.8 - The iptables 1.3.1 man page. This is an HTMLized version of the man page which is an excellent reference when reading/writing iptables rule-sets. Always have it at hand.
Ipsysctl 教程- 我写的关于 Linux 中 IP 系统控制的另一个教程。尝试列出所有可以在 Linux 中动态设置的 IP 变量的完整列表。
Ipsysctl tutorial - Another tutorial I have written about the IP System Control in Linux. A try to make a complete listing of all the IP variables that can be set on the fly in Linux.
Policy Routing using Linux - 这是一本关于 Linux 中策略路由的优秀书籍,现已在 Internet 上公开。写得很好,绝对值得购买。作者:马修·G·马什。
Policy Routing Using Linux - This is an excellent book that has now been opened up on the Internet regarding Policy routing in Linux. It is well written and most definitely worth buying. Written by Matthew G. Marsh.
安全增强型 Linux - 安全增强型 Linux (SELinux) 系统的官方网站,由国家安全局 (NSA) 作为概念验证而开发。SELinux 是一个细粒度的强制访问控制系统,它使您可以更好地控制谁可以做什么以及哪些进程拥有哪些权限等等。
Security-Enhanced Linux - The official site of the Security-Enhanced Linux (SELinux) system developed as a proof of concept by the National Security Agency (NSA). SELinux is a fine grained Mandatory Access Control system, which lets you have a much higher control on who can do what and what processes has what privileges, et cetera.
防火墙规则表- Stuart Clark 优雅地为该项目提供的一个小型 PDF 文档,它提供了一个参考表,您可以在其中以简单的方式编写防火墙所需的所有信息。
Firewall rules table - A small PDF document gracefully given to this project by Stuart Clark, which gives a reference form where you can write all of the information needed for your firewall, in a simple manner.
http://l7-filter.sourceforge.net/ - l7-filter 项目基本上是一组补丁和文件,使 iptables 和 netfilter 能够处理第 7 层过滤,主要用于 QoS 和流量统计。然而,它的过滤工作不太可靠,因为它会在实际阻止流量之前允许前几个数据包通过。
http://l7-filter.sourceforge.net/ - The l7-filter project is basically a set of patches and files to make iptables and netfilter able to handle layer 7 filtering, mainly for QoS and traffic accounting. It works less reliably for filtering however, since it will allow the first couple of packets through before actually blocking traffic.
http://www.netfilter.org/ - Netfilter 和 iptables 官方网站。对于每个想要在 Linux 中设置 iptables 和 Netfilter 的人来说,这是必须的。
http://www.netfilter.org/ - The official Netfilter and iptables site. It is a must for everyone wanting to set up iptables and Netfilter in linux.
http://www.insecure.org/nmap/ - Nmap 是最好、最知名的端口扫描器之一。在调试防火墙脚本时它非常有用。仔细看看它。
http://www.insecure.org/nmap/ - Nmap is one of the best, and most known, port scanners available. It is very useful when debugging your firewall scripts. Take a closer look at it.
http://www.netfilter.org/documentation/index.html#FAQ - 官方 Netfilter常见问题解答。当想知道 iptables 和 Netfilter 是什么时,这也是一个很好的起点。
http://www.netfilter.org/documentation/index.html#FAQ - The official Netfilter Frequently Asked Questions. Also a good place to start at when wondering what iptables and Netfilter is about.
http://www.netfilter.org/unreliable-guides/packet-filtering-HOWTO/index.html - Rusty Russells 不可靠的数据包过滤指南。由 iptables 和 Netfilter 的核心开发人员之一编写的关于使用 iptables 进行基本数据包过滤的优秀文档。
http://www.netfilter.org/unreliable-guides/packet-filtering-HOWTO/index.html - Rusty Russells Unreliable Guide to packet filtering. Excellent documentation about basic packet filtering with iptables written by one of the core developers of iptables and Netfilter.
http://www.netfilter.org/unreliable-guides/NAT-HOWTO/index.html - Rusty Russell 不可靠的网络地址转换指南。由核心开发人员之一 Rusty Russell 编写的关于 iptables 和 Netfilter 中网络地址转换的优秀文档。
http://www.netfilter.org/unreliable-guides/NAT-HOWTO/index.html - Rusty Russells Unreliable Guide to Network Address Translation. Excellent documentation about Network Address Translation in iptables and Netfilter written by one of the core developers, Rusty Russell.
http://www.netfilter.org/unreliable-guides/netfilter-hacking-HOWTO/index.html - Rusty Russells 不可靠的 Netfilter 黑客攻击方法。关于如何在 Netfilter 和 iptables 用户空间和内核空间代码库中编写代码的少数文档之一。这也是拉斯蒂·拉塞尔写的。
http://www.netfilter.org/unreliable-guides/netfilter-hacking-HOWTO/index.html - Rusty Russells Unreliable Netfilter Hacking HOW-TO. One of the few documentations on how to write code in the Netfilter and iptables user-space and kernel space code-base. This was also written by Rusty Russell.
http://www.linuxguruz.org/iptables/ - 优秀的链接页面,包含 Internet 上有关 iptables 和 Netfilter 的大多数页面的链接。还维护一个用于不同目的的 iptables 脚本列表。
http://www.linuxguruz.org/iptables/ - Excellent link-page with links to most of the pages on the Internet about iptables and Netfilter. Also maintains a list of iptables scripts for different purposes.
Policy Routing using Linux - 我读过的关于 Linux 上的策略路由的最好的书。当谈到 Linux 中的路由时,这是绝对必须的。作者:马修·G·马什。
Policy Routing using Linux - The best book I have ever read on Policy routing nad linux. This is an absolute must when it comes to routing in linux. Written by Matthew G. Marsh.
使用 DSCP 实施服务质量策略 - 有关思科 DSCP 实施的链接。这显示了 DSCP 中使用的一些类,等等。
Implementing Quality of Service Policies with DSCP - A link about the cisco implementation of DSCP. This shows some classes used in DSCP, and so on.
IETF SIP 工作组- SIP 似乎是“下一件大事”之一。基本上它是当今网络电话事实上的标准。正如您从工作组主页上的大量文档中可以看到的那样,它非常复杂,并且应该能够满足未来会议启动的几乎任何需求。它主要用于在已知用户之间建立对等连接,例如连接到 user@example.org 并建立到该用户的电话连接。这是处理所有 SIP 工作的 IETF 工作组。
IETF SIP Working Group - SIP is one of the "next big things" it seems. Basically it is the defacto standards for Internet telephony today. It is horribly complex as you can see from the amount of documentation on the working groups homepage, and should hopefully be able to cope with pretty much any needs of session initiation in the future. It is used mainly to setup peer to peer connections between known users, for example to connect to user@example.org and setup a phone connection to that user. This is the IETF Working group handling all SIP work.
IETF TLS 工作组- TLS 是一种传输层安全模型,是最常见的基于主机到服务器的安全机制之一。目前正在运行的版本是 1.1,截至撰写本文时,我们正在努力推出 1.2,以支持更新、更好的加密货币。这是发送和接收服务器公钥以及处理可信证书代理等的标准化方法。有关详细信息,请阅读本页上的 RFC。
IETF TLS Working Group - TLS is a transport layer security model that is one of the most common host to server based security mechanisms. The current version is running is 1.1 and work is ongoing to get 1.2 out the door with support for newer and better cryptos as of this writing. This is a standardized way of sending and receiving public keys for servers and handling trusted certificate agents etc. For more information, read the RFC's on this page.
IPSEC Howto - 这是 Linux 2.6 内核的官方 IPSEC Howto。它描述了 IPSEC 在 2.6 及更高版本的内核中如何工作,但是,它并不是详细了解 Linux 2.2 和 2.4 内核在 IPSEC 方面如何工作的地方。请访问FreeS/WAN站点以获取该信息。
IPSEC Howto - This is the official IPSEC howto for Linux 2.6 kernels. It describes how IPSEC works in the 2.6 kernels and up, however, it is not the place to find out exactly how the Linux 2.2 and 2.4 kernels worked when it comes to IPSEC. Go to the FreeS/WAN site for that information.
FreeS/WAN - 这是 FreeS/WAN 的官方网站,FreeS/WAN 是 Linux 2.2 和 2.4 内核系列的 IPSEC 实现。该站点包含 IPSEC 实施的文档和所有必要的下载。由于页面上讨论的几个原因,这项工作已停止,但仍将努力修复错误、文档和论坛。有关 Linux 2.6 内核的 IPSEC 实现,请查看IPSEC Howto站点及其信息。
FreeS/WAN - This is the official site for FreeS/WAN, an IPSEC implementation for the Linux 2.2 and 2.4 kernel series. This site contains documentation and all necessary downloads for the IPSEC implementation. This effort has been discontinued due to several reasons discussed on the page, but efforts will still be put into bugfixes, documentation and the forums. For an IPSEC implementation for Linux 2.6 kernels, please look at the IPSEC Howto site and the information there.
http://www.islandsoft.net/veerapen.html -关于 iptables 自动强化以及如何进行小更改以使您的计算机自动将恶意站点添加到 iptables 中的特殊禁止列表中的精彩讨论。
http://www.islandsoft.net/veerapen .html -Excellent discussion on automatic hardening of iptables and how to make small changes that will make your computer automatically add hostile sites to a special ban list in iptables .
/etc/protocols - 取自 Slackware 发行版的示例协议文件。这可用于找出不同协议的协议号,例如 IP、ICMP 或 TCP 协议。
/etc/protocols - An example protocols file taken from the Slackware distribution. This can be used to find out what protocol number different protocols have, such as the IP, ICMP or TCP protocols have.
/etc/services - 取自 Slackware 发行版的示例服务文件。这非常适合偶尔阅读,特别是如果您想基本了解不同端口上运行的协议。
/etc/services - An example services file taken from the Slackware distribution. This is extremely good to get used to reading once in a while, specifically if you want to get a basic look at what protocols runs on different ports.
互联网号码分配机构- IANA 是负责以有序的方式固定不同协议中的所有号码的组织。如果任何人要对协议进行特定添加(例如,添加新的 TCP 选项),他们需要联系 IANA,后者将分配所请求的号码。换句话说,这是一个需要密切关注的极其重要的网站。
Internet Assigned Numbers Authority - The IANA is the organisation that is responsible for fixing all numbers in the different protocols in an orderly fashion. If anyone has a specific addition to make to a protocol (for example, adding a new TCP option), they need to contact the IANA, which will assign the numbers requested. In other words, extremely important site to keep an eye on.
RFC-editor.org - 这是一个快速有序地查找 RFC 文档的优秀网站。用于搜索 RFC 文档以及有关 RFC 社区的一般信息(即勘误表、新闻等)的功能。
RFC-editor.org - This is an excellent site for finding RFC documents in a fast and orderly way. Functions for searching RFC documents, and general information about the RFC community (I.e., errata, news, et cetera).
互联网工程任务组- 这是制定和维护互联网标准的最大团体之一。他们负责维护 RFC 存储库,由一大群公司和个人组成,他们共同努力确保互联网的互操作性。
Internet Engineering Task Force - This is one of the biggest groups when it comes to setting and maintaining Internet standards. They are the ones maintaining the RFC repository, and consist of a large group of companies and individuals that work together to ensure the interoperability of the Internet.
Linux 高级路由和流量控制指南- 此站点托管 Linux 高级路由和流量控制指南。它是有关 Linux 高级路由的最大、最好的文档之一。由伯特休伯特维护。
Linux Advanced Routing and Traffic Control HOW-TO - This site hosts the Linux Advanced Routing and Traffic Control HOWTO. It is one of the biggest and best documents regarding Linux advanced routing. Maintained by Bert Hubert.
Paksecured Linux 内核补丁- 包含 Matthew G. Marsh 编写的所有内核补丁的站点。其中,FTOS 补丁可在此处获取。
Paksecured Linux Kernel patches - A site containing all of the kernel patches written by Matthew G. Marsh. Among others, the FTOS patch is available here.
ULOGD 项目页面- ULOGD 站点的主页。
ULOGD project page - The homepage of the ULOGD site.
Linux文档项目 是一个很棒的文档站点。Linux 的大多数大型文档都可以在这里找到,如果 TLDP 中没有,您将必须非常仔细地在网上搜索。如果您想了解更多信息,请查看此网站。
The Linux Documentation Project is a great site for documentation. Most big documents for Linux is available here, and if not in the TLDP, you will have to search the net very carefully. If there is anything you want to know more about, check this site out.
Snort - 这是一个优秀的开源“网络入侵检测系统”(NIDS),它在它看到的数据包中查找签名,如果它看到某种攻击或入侵的签名,它可以执行不同的操作被定义(通知管理员,或采取行动,或只是记录它)。
Snort - this is an excellent open source "network intrusion detection system" (NIDS) which looks for signatures in the packets that it sees, and if it sees a signature of some kind of attack or break-in it can do different actions that can be defined (notifying the administrator, or take action, or simply logging it).
Tripwire - tripwire 是一个优秀的安全工具,可用于查找主机入侵。它对配置文件中指定的所有文件进行校验和,然后在每次运行时告诉管理员任何被非法方式篡改的文件。
Tripwire - tripwire is an excellent security tool which can be used to find out about host intrusions. It makes checksums of all the files specified in a configuration file, and then it tells the administrator about any files that has been tampered with in an illegit way every time it is run.
Squid - 这是市场上最知名的网络代理之一。它是开源的,并且免费。它可以执行在流量实际到达您的网络服务器之前应完成的多项过滤任务,以及为您的网络执行标准的网络缓存功能。
Squid - This is one of the most known webproxies available on the market. It is open source, and free. It can do several of the filtering tasks that should be done before the traffic actually hits your webserver, as well as doing the standard webcaching functions for your networks.
http://kalamazoolinux.org/presentations/20010417/conntrack.html - 该演示文稿包含对 conntrack 模块及其在 Netfilter 中的工作的精彩解释。如果您对 conntrack 的更多文档感兴趣,这是“必读”。
http://kalamazoolinux.org/presentations/20010417/conntrack.html - This presentation contains an excellent explanation of the conntrack modules and their work in Netfilter. If you are interested in more documentation on conntrack, this is a "must read".
http://www.docum.org - 有关 Linux 中 CBQ、tc 和 ip 命令的精彩信息。拥有有关这些程序的任何信息的少数网站之一。由 Stef Coene 维护。
http://www.docum.org - Excellent information about the CBQ, tc and the ip commands in Linux. One of the few sites that has any information at all about these programs. Maintained by Stef Coene.
http://lists.samba.org/m ailman/listinfo/netfilter - 官方 Netfilter 邮件列表。如果您对本文档或此处的任何其他链接中未涵盖的内容有疑问,则非常有用。
http://lists.samba.org/m ailman/listinfo/netfilter- The official Netfilter mailing-list. Extremely useful in case you have questions about something not covered in this document or any of the other links here.
当然还有 iptables 源代码、文档和帮助过我的个人。
And of course the iptables source, documentation and individuals who helped me.
我要感谢以下人员对本文档的帮助:
I would like to thank the following people for their help on this document:
Fabrice Marie,对我糟糕的语法和拼写进行了重大更新。也非常感谢您使用 make 文件等将教程更新为 DocBook 格式。
Fabrice Marie, For major updates to my horrible grammar and spelling. Also a huge thanks for updating the tutorial to DocBook format with make files etc.
Marc Boucher,在使用状态匹配代码的某些方面帮助我。
Marc Boucher, For helping me out on some aspects on using the state matching code.
Frode E. Nyboe,大大改进了 rc.firewall规则,并在我重写规则集并成为将多表遍历引入同一文件的人时给予了很大启发。
Frode E. Nyboe, For greatly improving the rc.firewall rules and giving great inspiration while i was to rewrite the rule-set and being the one who introduced the multiple table traversing into the same file.
Chapman Brad、 Alexander W. Janssen,两人都让我意识到我对数据包如何穿越基本 NAT 和过滤器表以及它们出现的顺序的思考是错误的。
Chapman Brad, Alexander W. Janssen, Both for making me realize I was thinking wrong about how packets traverse the basic NAT and filters tables and in which order they show up.
Michiel Brandenburg、 Myles Uyema帮助我解决了一些状态匹配代码并使其正常工作。
Michiel Brandenburg, Myles Uyema, For helping me out with some of the state matching code and getting it to work.
Kent `Artech' Stahre,帮助我处理图形。我知道我在图形方面很糟糕,而你比我认识的大多数做图形的人都要好;)。也感谢您检查教程中的错误等。
Kent `Artech' Stahre, For helping me out with the graphics. I know I suck at graphics, and you're better than most I know who do graphics;). Also thanks for checking the tutorial for errors etc.
Anders 'DeZENT' Johansson,向我暗示奇怪的 ISP 等使用互联网上的保留网络,或者至少在互联网上为您服务。
Anders 'DeZENT' Johansson, For hinting me about strange ISPs and so on that uses reserved networks on the Internet, or at least on the Internet for you.
Jeremy `Spliffy' Smith,为我提供了一些可能会给人们带来麻烦的东西的提示,并尝试了它并检查了我所写内容中的错误。
Jeremy `Spliffy' Smith, For giving me hints at stuff that might screw up for people and for trying it out and checking for errors in what I've written.
版本 1.2.2(2006 年 11 月 19 日) https://www.frozenux.net/iptables-tutorial 奥斯卡·安德烈亚森 贡献者:Jens Larsson 和 GW Haywood。 版本 1.2.1(2006 年 9 月 29 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Ortwin Glueck、Mao、Marcos Roberto Greiner、Christian Font、 塔蒂亚娜、安德鲁斯、阿列克谢·杜谢金、野野垣达也和弗雷德。 版本 1.2.0(2005 年 7 月 20 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Corey Becker、Neil Perrins、Watz 和西班牙语翻译团队。 版本 1.1.19(2003 年 5 月 21 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Peter van Kampen、Xavier Bartol、Jon Anderson、Thorsten Bremer 和西班牙语翻译团队。 版本 1.1.18(2003 年 4 月 24 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Stuart Clark、Robert PJ Day、Mark Orenstein 和 Edmond Shwayri。 版本 1.1.17(2003 年 4 月 6 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Geraldo Amaral Filho、Ondrej Suchy、Dino Conti、Robert PJ Day、 维列夫·迪莫 (Velev Dimo)、斯宾塞·鲁瑟 (Spencer Rouser)、戴维诺斯 (Daveonos)、阿曼达·希克曼 (Amanda Hickman)、奥勒·琼森 (Olle Jonsson) 和 本特·阿斯普瓦尔. 版本 1.1.16(2002 年 12 月 16 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Clemens Schwaighower、Uwe Dippel 和 Dave Wreski。 版本 1.1.15(2002 年 11 月 13 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Mark Sonarte、A. Lester Buck、Robert PJ Day、Togan Muftuoglu、 安东尼·斯通、马修·F·巴恩斯和奥托·马泰卡。 版本 1.1.14(2002 年 10 月 14 日) https://www.frozenux.net/iptables-tutorial 作者:奥斯卡·安德烈森 贡献者:Carol Anne、Manuel Minzoni、Yves Soun、Miernik、Uwe Dippel、 戴夫·克利佩克和艾迪·洛·詹森。 版本 1.1.13(2002 年 8 月 22 日) http://iptables-tutorial.haringstad.com 作者:奥斯卡·安德烈森 贡献者:很多人报告 HTML 版本不好。 版本 1.1.12(2002 年 8 月 19 日) http://www.netfilter.org/tutorial/ 作者:奥斯卡·安德烈森 贡献者:Peter Schubnell、Stephen J. Lawrence、Uwe Dippel、Bradley 迪尔格、维加德·恩根、克利福德·凯特、亚历山德罗·奥利维拉、托尼·恩肖、 哈拉尔德·韦尔特、尼克·安德鲁和斯捷潘·卡萨尔。 版本 1.1.11(2002 年 5 月 27 日) http://www.netfilter.org/tutorial/ 作者:奥斯卡·安德烈森 贡献者:Steve Hnizdur、Lonni Friedman、Jelle Kalf、Harald Welte、 瓦伦蒂娜·巴里奥斯和托尼·恩肖。 版本 1.1.10(2002 年 4 月 12 日) http://www.boingworld.com/workshops/linux/iptables-tutorial/ 作者:奥斯卡·安德烈森 贡献者:耶勒·卡尔夫、西奥多·亚历山德罗夫、保罗·科贝特、罗德里戈 鲁比拉·布兰科、阿利斯泰尔·托纳、马修·G·马什、乌韦·迪佩尔、埃文 内默森和马塞尔·J·E·莫尔。 版本 1.1.9(2002 年 3 月 21 日) http://www.boingworld.com/workshops/linux/iptables-tutorial/ 作者:奥斯卡·安德烈森 贡献者:Vince Herried、Togan Muftuoglu、Galen Johnson、Kelly Ashe、Janne 约翰逊、托马斯·斯梅茨、彼得·霍斯特、米奇·兰德斯、尼尔·乔利、杰尔·卡尔夫、 杰森·林和埃文·内默森。 版本 1.1.8(2002 年 3 月 5 日) http://www.boingworld.com/workshops/linux/iptables-tutorial/ 作者:奥斯卡·安德烈森 版本 1.1.7(2002 年 2 月 4 日) http://www.boingworld.com/workshops/linux/iptables-tutorial/ 作者:奥斯卡·安德烈森 贡献者:Parimi Ravi、Phil Schultz、Steven McClintoc、Bill Dossett、 Dave Wreski、Erik Sjölund、Adam Mansbridge、Vasoo Veerapen、Aladdin 和 生锈的拉塞尔。 版本 1.1.6(2001 年 12 月 7 日) http://people.unix-fu.org/andreasson/ 作者:奥斯卡·安德烈森 贡献者:Jim Ramsey、Phil Schultz、Göran Båge、Doug Monroe、Jasper 艾克玛、库尔特·利伯、克里斯·塔伦、克里斯·马丁、乔纳斯·帕什、Jan 拉巴诺夫斯基、罗德里戈·R·布兰科、雅科·范科尔和戴夫·雷斯基。 版本 1.1.5(2001 年 11 月 14 日) http://people.unix-fu.org/andreasson/ 作者:奥斯卡·安德烈森 贡献者:Fabrice Marie、Merijn Schering 和 Kurt Lieber。 版本 1.1.4(2001 年 11 月 6 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 贡献者:Stig W. Jensen、Steve Hnizdur、Chris Pluta 和 Kurt Lieber。 版本 1.1.3(2001 年 10 月 9 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 贡献者:Joni Chu、N.Emile Akabi-Davis 和 Jelle Kalf。 版本 1.1.2(2001 年 9 月 29 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 版本 1.1.1(2001 年 9 月 26 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 贡献者:戴夫·理查森。 版本 1.1.0(2001 年 9 月 15 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 版本 1.0.9(2001 年 9 月 9 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 版本 1.0.8(2001 年 9 月 7 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 版本 1.0.7(2001 年 8 月 23 日) http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 贡献者:法布里斯·玛丽。 版本1.0.6 http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 版本1.0.5 http://people.unix-fu.org/andreasson 作者:奥斯卡·安德烈森 贡献者:法布里斯·玛丽。
Version 1.2.2 (19 Nov 2006) https://www.frozentux.net/iptables-tutorial By Oskar Andreasson Contributors: Jens Larsson and G. W. Haywood. Version 1.2.1 (29 Sep 2006) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Ortwin Glueck, Mao, Marcos Roberto Greiner, Christian Font, Tatiana, Andrius, Alexey Dushechkin, Tatsuya Nonogaki and Fred. Version 1.2.0 (20 July 2005) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Corey Becker, Neil Perrins, Watz and Spanish translation team. Version 1.1.19 (21 May 2003) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Peter van Kampen, Xavier Bartol, Jon Anderson, Thorsten Bremer and Spanish Translation Team. Version 1.1.18 (24 Apr 2003) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Stuart Clark, Robert P. J. Day, Mark Orenstein and Edmond Shwayri. Version 1.1.17 (6 Apr 2003) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Geraldo Amaral Filho, Ondrej Suchy, Dino Conti, Robert P. J. Day, Velev Dimo, Spencer Rouser, Daveonos, Amanda Hickman, Olle Jonsson and Bengt Aspvall. Version 1.1.16 (16 Dec 2002) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Clemens Schwaighower, Uwe Dippel and Dave Wreski. Version 1.1.15 (13 Nov 2002) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Mark Sonarte, A. Lester Buck, Robert P. J. Day, Togan Muftuoglu, Antony Stone, Matthew F. Barnes and Otto Matejka. Version 1.1.14 (14 Oct 2002) https://www.frozentux.net/iptables-tutorial By: Oskar Andreasson Contributors: Carol Anne, Manuel Minzoni, Yves Soun, Miernik, Uwe Dippel, Dave Klipec and Eddy L O Jansson. Version 1.1.13 (22 Aug 2002) http://iptables-tutorial.haringstad.com By: Oskar Andreasson Contributors: Tons of people reporting bad HTML version. Version 1.1.12 (19 Aug 2002) http://www.netfilter.org/tutorial/ By: Oskar Andreasson Contributors: Peter Schubnell, Stephen J. Lawrence, Uwe Dippel, Bradley Dilger, Vegard Engen, Clifford Kite, Alessandro Oliveira, Tony Earnshaw, Harald Welte, Nick Andrew and Stepan Kasal. Version 1.1.11 (27 May 2002) http://www.netfilter.org/tutorial/ By: Oskar Andreasson Contributors: Steve Hnizdur, Lonni Friedman, Jelle Kalf, Harald Welte, Valentina Barrios and Tony Earnshaw. Version 1.1.10 (12 April 2002) http://www.boingworld.com/workshops/linux/iptables-tutorial/ By: Oskar Andreasson Contributors: Jelle Kalf, Theodore Alexandrov, Paul Corbett, Rodrigo Rubira Branco, Alistair Tonner, Matthew G. Marsh, Uwe Dippel, Evan Nemerson and Marcel J.E. Mol. Version 1.1.9 (21 March 2002) http://www.boingworld.com/workshops/linux/iptables-tutorial/ By: Oskar Andreasson Contributors: Vince Herried, Togan Muftuoglu, Galen Johnson, Kelly Ashe, Janne Johansson, Thomas Smets, Peter Horst, Mitch Landers, Neil Jolly, Jelle Kalf, Jason Lam and Evan Nemerson. Version 1.1.8 (5 March 2002) http://www.boingworld.com/workshops/linux/iptables-tutorial/ By: Oskar Andreasson Version 1.1.7 (4 February 2002) http://www.boingworld.com/workshops/linux/iptables-tutorial/ By: Oskar Andreasson Contributors: Parimi Ravi, Phil Schultz, Steven McClintoc, Bill Dossett, Dave Wreski, Erik Sjölund, Adam Mansbridge, Vasoo Veerapen, Aladdin and Rusty Russell. Version 1.1.6 (7 December 2001) http://people.unix-fu.org/andreasson/ By: Oskar Andreasson Contributors: Jim Ramsey, Phil Schultz, Göran Båge, Doug Monroe, Jasper Aikema, Kurt Lieber, Chris Tallon, Chris Martin, Jonas Pasche, Jan Labanowski, Rodrigo R. Branco, Jacco van Koll and Dave Wreski. Version 1.1.5 (14 November 2001) http://people.unix-fu.org/andreasson/ By: Oskar Andreasson Contributors: Fabrice Marie, Merijn Schering and Kurt Lieber. Version 1.1.4 (6 November 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Contributors: Stig W. Jensen, Steve Hnizdur, Chris Pluta and Kurt Lieber. Version 1.1.3 (9 October 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Contributors: Joni Chu, N.Emile Akabi-Davis and Jelle Kalf. Version 1.1.2 (29 September 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Version 1.1.1 (26 September 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Contributors: Dave Richardson. Version 1.1.0 (15 September 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Version 1.0.9 (9 September 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Version 1.0.8 (7 September 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Version 1.0.7 (23 August 2001) http://people.unix-fu.org/andreasson By: Oskar Andreasson Contributors: Fabrice Marie. Version 1.0.6 http://people.unix-fu.org/andreasson By: Oskar Andreasson Version 1.0.5 http://people.unix-fu.org/andreasson By: Oskar Andreasson Contributors: Fabrice Marie.
版本 1.1,2000 年 3 月
Version 1.1, March 2000
版权所有 (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 每个人都可以复制和分发本许可文档的逐字副本,但不允许更改。
Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
本许可证的目的是使手册、教科书或其他书面文档在自由意义上“自由”:确保每个人都有复制和重新分发的有效自由,无论是否进行修改,无论是商业性还是非商业性。其次,该许可证为作者和出版商保留了一种获得其作品荣誉的方式,同时不被认为对他人所做的修改负责。
The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
该许可证是一种“copyleft”,这意味着该文档的衍生作品本身必须在相同意义上是免费的。它补充了 GNU 通用公共许可证,这是专为自由软件设计的 Copyleft 许可证。
This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
我们设计此许可证是为了将其用作自由软件的手册,因为自由软件需要自由文档:自由程序应该附带提供与软件相同自由的手册。但本许可不限于软件手册;它可用于任何文本作品,无论主题如何或是否以印刷书籍形式出版。我们主要推荐此许可证用于以指导或参考为目的的作品。
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
本许可证适用于任何手册或其他作品,其中包含版权所有者发布的声明,表明可以根据本许可证的条款进行分发。下面的“文档”指任何此类手册或作品。任何公众成员都是被许可人,并被称为“您”。
This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".
本文档的“修改版本”是指包含本文档或其一部分的任何作品,无论是逐字复制还是经过修改和/或翻译成另一种语言。
A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
“第二部分”是文档的指定附录或前言部分,专门处理文档的出版商或作者与文档的整体主题(或相关事项)的关系,并且不包含任何可能直接涉及的内容在整个主题内。(例如,如果该文档的一部分是数学教科书,则第二部分可能不会解释任何数学。)这种关系可能是与主题或相关事项的历史联系,或者是法律、商业、哲学、关于他们的道德或政治立场。
A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
“不变部分”是某些次要部分,其标题在说明文档根据本许可证发布的通知中指定为不变部分的标题。
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.
“封面文本”是在通知中列出的某些简短文本段落,如封面文本或封底文本,说明文档是根据本许可证发布的。
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.
文件的“透明”副本是指机器可读的副本,以公众可获得规范的格式表示,其内容可以使用通用文本编辑器直接查看和编辑,或者(对于由像素组成的图像)通用绘画程序或(对于绘图)一些广泛使用的绘图编辑器,并且适合输入到文本格式化程序或自动转换为适合输入到文本格式化程序的各种格式。以透明文件格式制作的副本,如果其标记旨在阻止或阻止读者进行后续修改,则该副本不是透明的。非“透明”的副本称为“不透明”。
A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".
透明副本的合适格式示例包括无标记的纯 ASCII、Texinfo 输入格式、LaTeX 输入格式、使用公开可用的 DTD 的 SGML 或 XML,以及为人工修改而设计的符合标准的简单 HTML。不透明格式包括 PostScript、PDF、只能由专有文字处理器读取和编辑的专有格式、DTD 和/或处理工具通常不可用的 SGML 或 XML,以及由某些文字处理器生成的机器生成的 HTML仅用于输出目的。
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.
对于印刷书籍,“扉页”是指扉页本身,以及清晰地保存本许可证要求在扉页中显示的材料所需的后续页面。对于没有任何标题页的格式的作品,“标题页”是指靠近作品标题最突出的外观、位于文本正文开头之前的文本。
The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
您可以在任何商业或非商业媒介上复制和分发本文档,前提是本许可证、版权声明以及说明本许可证适用于本文档的许可证声明均复制到所有副本中,并且您不添加任何其他条件本许可证的内容。您不得使用技术措施阻碍或控制您制作或分发的副本的阅读或进一步复制。但是,您可以接受补偿以换取副本。如果您分发足够多的副本,您还必须遵守第 3 节中的条件。
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
您还可以在上述相同条件下出借副本,并且可以公开展示副本。
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
如果您出版的文档印刷副本数量超过 100,并且文档的许可声明需要封面文本,则您必须将副本附在封面上,封面上清晰易读地包含所有这些封面文本: 封面上的封面文本,和封底文字位于封底。两个封面还必须清楚易读地表明您是这些副本的出版商。封面必须呈现完整的标题,标题的所有文字都同样突出和可见。您还可以在封面上添加其他材料。仅限于封面更改的复制,只要保留文档标题并满足这些条件,在其他方面就可以被视为逐字复制。
If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
如果任一封面所需的文本太大而无法清晰显示,则应将列出的第一个文本(尽可能多地合理放置)放在实际封面上,并将其余内容继续放在相邻的页面上。
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
如果您发布或分发的文档的不透明副本数量超过 100,则必须在每个不透明副本中附上机器可读的透明副本,或者在每个不透明副本中注明一个可公开访问的计算机网络位置,其中包含完整的信息。该文档的透明副本,不含任何添加材料,一般网络使用公众可以使用公共标准网络协议免费匿名下载。如果您使用后一个选项,当您开始大量分发不透明副本时,您必须采取合理谨慎的步骤,
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
我们要求(但不是要求)您在重新分发大量副本之前与文档的作者联系,以便他们有机会为您提供文档的更新版本。
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
您可以根据上述第 2 节和第 3 节的条件复制和分发本文档的修改版本,前提是您完全按照本许可证发布修改版本,并且修改版本填补了文档的角色,从而许可分发和修改修改后的版本交给拥有该副本的任何人。另外,您必须在修改版本中执行以下操作:
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
在扉页(以及封面,如果有)中使用与文档以及以前版本(如果有的话,应该在文档的历史记录部分中列出)不同的标题。如果该版本的原始发行商允许,您可以使用与先前版本相同的标题。
Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
在扉页上列出作为作者、对修改版本中的修改负责的一个或多个个人或实体,以及文档的至少五位主要作者(所有主要作者,如果其少于五)。
List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).
在扉页上注明修改版本的出版商名称,即出版商。
State on the Title page the name of the publisher of the Modified Version, as the publisher.
保留文档的所有版权声明。
Preserve all the copyright notices of the Document.
在其他版权声明旁边添加适合您的修改的版权声明。
Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
在版权声明之后立即包含一份许可声明,允许公众根据本许可证的条款使用修改版本,其形式如下面的附录所示。
Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
在该许可通知中保留文档许可通知中给出的不变部分和所需封面文本的完整列表。
Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
包含本许可证的未更改副本。
Include an unaltered copy of this License.
保留标题为“历史”的部分及其标题,并向其中添加一个项目,至少说明扉页上给出的修改版本的标题、年份、新作者和出版商。如果文档中没有标题为“历史”的部分,请创建一个说明标题页上给出的文档标题、年份、作者和出版商,然后添加一个描述上一句中所述的修改版本的项目。
Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
保留文档中给出的网络位置(如果有),以便公众访问文档的透明副本,同样保留文档中给出的其所基于的先前版本的网络位置。这些可以放在“历史”部分。您可以省略至少在文档本身之前四年发布的作品的网络位置,或者如果它所引用的版本的原始出版商给予许可。
Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
在任何标题为“致谢”或“奉献”的部分中,保留该部分的标题,并在该部分中保留其中给出的每个贡献者致谢和/或奉献的所有实质内容和语气。
In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
保留文档的所有不变部分,其文本和标题不变。章节编号或同等内容不被视为章节标题的一部分。
Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
删除标题为“认可”的任何部分。修改版本中可能不包含此类部分。
Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.
请勿将任何现有部分重新命名为“认可”或与任何不变部分的标题发生冲突。
Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.
如果修改版本包含符合次要部分资格的新的前言部分或附录,并且不包含从文档复制的材料,则您可以选择将这些部分中的部分或全部指定为不变。为此,请将其标题添加到修改版本的许可声明中的不变部分列表中。这些标题必须与任何其他部分标题不同。
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
您可以添加标题为“认可”的部分,前提是它只包含各方对您的修改版本的认可 - 例如,同行评审的声明或文本已被某个组织批准为标准的权威定义。
You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
您可以将最多 5 个单词的段落作为封面文本,将最多 25 个单词的段落作为封底文本添加到修改版本中封面文本列表的末尾。任何一个实体(或通过其安排)只能添加一段封面文本和一段封底文本。如果文档已包含同一封面的封面文本,且该封面文本由您之前添加或由您代表的同一实体做出安排,则您不得添加其他内容;但您可以在获得添加旧版本的前一发布者的明确许可后更换旧版本。
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
文档的作者和出版商未根据本许可证授予使用其姓名进行任何修改版本的宣传或主张或暗示认可的许可。
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
您可以根据上述第 4 节中针对修改版本定义的条款,将本文档与根据本许可证发布的其他文档合并,前提是您在组合中包含所有未经修改的原始文档的所有不变部分,并将它们全部列出作为您的组合作品的许可声明中的不变部分。
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.
组合作品只需包含本许可证的一份副本,多个相同的不变部分可以用一份副本替换。如果存在多个具有相同名称但内容不同的不变部分,请通过在其末尾的括号中添加该部分的原始作者或出版商的名称(如果已知),使每个此类部分的标题唯一,否则,唯一的号码。对组合作品的许可声明中不变章节列表中的章节标题进行相同的调整。
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
合并时,必须将各个原始文件中标题为“历史”的任何部分合并起来,形成一个标题为“历史”的部分;同样,将标题为“致谢”的任何部分和标题为“奉献”的任何部分合并起来。您必须删除所有标题为“认可”的部分。
In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."
您可以制作一个包含本文档和根据本许可证发布的其他文档的集合,并用集合中包含的单个副本替换各个文档中本许可证的各个副本,前提是您遵循本许可证的规则在所有其他方面逐字复制每份文件。
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
您可以从这样的集合中提取单个文档,并根据本许可证单独分发它,前提是您将本许可证的副本插入到提取的文档中,并在有关逐字复制该文档的所有其他方面遵循本许可证。
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
在存储或分发介质的卷中或上的本文档或其派生品与其他单独且独立的文档或作品的汇编,不作为一个整体算作本文档的修改版本,前提是没有声明汇编版权编译。这样的编译称为“聚合”,并且本许可证不适用于与本文档一起编译的其他独立作品,因为它们是这样编译的,如果它们本身不是本文档的衍生作品。
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.
如果第 3 节的封面文本要求适用于文档的这些副本,则如果文档少于整个聚合的四分之一,则文档的封面文本可以放置在仅围绕聚合内的文档的封面上。否则,它们必须出现在整个集合周围的封面上。
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.
翻译被视为一种修改,因此您可以根据第 4 节的条款分发文档的翻译版本。用翻译替换不变部分需要获得其版权所有者的特别许可,但除了以下内容之外,您还可以包括部分或全部不变部分的翻译这些不变部分的原始版本。您可以包含本许可证的翻译版本,前提是您还包含本许可证的原始英文版本。如果本许可证的翻译版本与英文原版之间存在分歧,则以英文原版为准。
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.
除非本许可证明确规定,否则您不得复制、修改、再许可或分发本文档。任何其他复制、修改、再许可或分发本文档的尝试均无效,并将自动终止您在本许可证下的权利。但是,根据本许可证从您那里收到副本或权利的各方只要完全遵守规定,其许可证就不会被终止。
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
自由软件基金会可能会不时发布 GNU 自由文档许可证的新修订版本。此类新版本在精神上与当前版本相似,但在解决新问题或疑虑方面可能在细节上有所不同。请参阅http://www.gnu.org/copyleft/。
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
每个版本的许可证都有一个独特的版本号。如果文档指定本许可证的特定编号版本“或任何更高版本”适用于它,您可以选择遵循该指定版本或任何已发布的更高版本(不作为草案)由自由软件基金会制定。如果文档未指定本许可证的版本号,您可以选择自由软件基金会曾经发布的任何版本(不是草稿)。
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
要在您编写的文档中使用本许可证,请在文档中包含许可证的副本,并将以下版权和许可证声明放在标题页之后:
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
版权所有 (c) 年份您的名字。根据 GNU 自由文档许可证 1.1 版或自由软件基金会发布的任何更高版本的条款,授予复制、分发和/或修改本文档的许可;不变部分为“列出其标题”,封面文本为“列表”,封底文本为“列表”。许可证的副本包含在标题为“GNU 自由文档许可证”的部分中。
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".
如果没有不变部分,请写“没有不变部分”,而不是说哪些部分是不变的。如果您没有封面文本,请写“无封面文本”而不是“封面文本正在列表”;封底文本也是如此。
If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
如果您的文档包含重要的程序代码示例,我们建议您根据您选择的自由软件许可证(例如 GNU 通用公共许可证)并行发布这些示例,以允许它们在自由软件中使用。
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
第 2 版,1991 年 6 月
Version 2, June 1991
版权所有 (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 每个人都可以复制和分发本许可文档的逐字副本,但不允许更改。
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
大多数软件的许可证旨在剥夺您共享和更改软件的自由。相比之下,GNU 通用公共许可证旨在保证您共享和更改自由软件的自由,以确保该软件对所有用户都是免费的。本通用公共许可证适用于自由软件基金会的大部分软件以及作者承诺使用它的任何其他程序。(其他一些自由软件基金会软件由 GNU 库通用公共许可证涵盖。)您也可以将其应用到您的程序中。
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
当我们谈论自由软件时,我们指的是自由,而不是价格。我们的通用公共许可证旨在确保您可以自由分发免费软件的副本(如果您愿意,可以对该服务收费),您可以收到源代码或可以在需要时获取它,您可以更改软件或在新的免费程序中使用它的一部分;并且你知道你可以做这些事情。
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
为了保护您的权利,我们需要做出限制,禁止任何人剥夺您的这些权利或要求您放弃这些权利。如果您分发该软件的副本或对其进行修改,这些限制将转化为您的某些责任。
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
例如,如果您分发此类程序的副本,无论是免费还是收费,您都必须向接收者授予您拥有的所有权利。您必须确保他们也收到或可以获得源代码。您必须向他们展示这些条款,以便他们了解自己的权利。
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
我们通过两个步骤保护您的权利:(1) 对软件进行版权保护,(2) 向您提供此许可证,该许可证授予您复制、分发和/或修改软件的合法许可。
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
此外,为了保护每个作者和我们自己,我们希望确保每个人都明白此免费软件不提供任何保证。如果该软件被其他人修改并传播,我们希望其接收者知道他们所拥有的不是原始软件,因此其他人引入的任何问题都不会影响原始作者的声誉。
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
最后,任何自由程序都会不断受到软件专利的威胁。我们希望避免免费程序的再分发者单独获得专利许可的危险,从而实际上使该程序成为专有的。为了防止这种情况发生,我们明确表示任何专利都必须授权给所有人免费使用,否则根本不授权。
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
复制、分发和修改的具体条款和条件如下。
The precise terms and conditions for copying, distribution and modification follow.
本许可证适用于任何程序或其他作品,其中包含版权所有者发出的通知,表明可以根据本通用公共许可证的条款进行分发。下面的“程序”是指任何此类程序或作品,“基于该程序的作品”是指该程序或版权法规定的任何衍生作品:也就是说,包含该程序或该程序的一部分的作品。逐字或经过修改和/或翻译成另一种语言。(下文中,术语“修改”包括但不限于翻译。)每个被许可人均称为“您”。
本许可证不涵盖复制、分发和修改以外的活动;它们超出了其范围。运行本程序的行为不受限制,并且仅当其内容构成基于本程序的作品时(独立于通过运行本程序而完成的作品),本程序的输出才被涵盖。这是否属实取决于该计划的作用。
This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
您可以在收到本程序源代码时通过任何媒介复制和分发该程序源代码的逐字副本,前提是您在每个副本上显着且适当地发布适当的版权声明和免责声明;完整保留所有涉及本许可证以及不存在任何保证的通知;并向本程序的任何其他接收者提供本许可证的副本以及本程序。
您可以对转让副本的实际行为收取费用,并且您可以选择提供保修保护以换取费用。
You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
您可以修改您的程序或其任何部分的一个或多个副本,从而形成基于该程序的作品,并根据上述第 1 条的条款复制和分发此类修改或作品,前提是您还满足所有这些条件:
您必须让修改后的文件带有显着的通知,说明您更改了文件以及任何更改的日期。
您必须使您分发或发布的全部或部分包含或源自本程序或其任何部分的任何作品,根据本许可证的条款作为一个整体免费许可给所有第三方。
如果修改后的程序在运行时通常以交互方式读取命令,则当以最普通的方式开始运行此类交互使用时,您必须使其打印或显示一个公告,其中包括适当的版权声明和不存在任何保证(或否则,表示您提供保证)并且用户可以在这些条件下重新分发程序,并告诉用户如何查看本许可证的副本。(例外:如果程序本身是交互式的,但通常不打印这样的公告,则您基于该程序的作品不需要打印公告。)
这些要求适用于整个修改后的作品。如果该作品的可识别部分并非源自本程序,并且可以合理地认为其本身是独立且单独的作品,则当您将这些部分作为单独的作品分发时,本许可及其条款不适用于这些部分。但是,当您将相同的部分作为基于本程序的作品的一部分进行分发时,该整体的分发必须遵循本许可证的条款,其对其他被许可人的许可延伸至整个整体,从而延伸至每个以及每个部分,无论是谁写的。
因此,本节的目的并不是主张权利或质疑您对完全由您撰写的作品的权利;相反,其目的是行使控制基于该程序的衍生作品或集体作品的分发的权利。
此外,仅将不基于本程序的另一作品与本程序(或基于本程序的作品)聚集在存储或分发介质的卷上并不会将其他作品纳入本许可的范围。
You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
您可以根据上述第 1 节和第 2 节的条款以目标代码或可执行形式复制和分发本程序(或第 2 节中基于该程序的作品),前提是您还执行以下操作之一:
随附完整的相应机器可读源代码,该源代码必须根据上述第 1 节和第 2 节的条款在通常用于软件交换的介质上分发;或者,
随附一份有效期至少三年的书面报价,向任何第三方提供相应源代码的完整机器可读副本,费用不超过您实际执行源代码分发的成本,并根据上述第 1 节和第 2 节关于通常用于软件交换的介质的条款;或者,
随附您收到的有关分发相应源代码的要约信息。(此替代方案仅适用于非商业分发,并且仅当您根据上述 b 小节收到带有此类报价的目标代码或可执行形式的程序时。)
作品的源代码是指对其进行修改的作品的首选形式。对于可执行作品,完整的源代码意味着它包含的所有模块的所有源代码,加上任何关联的接口定义文件,加上用于控制可执行文件的编译和安装的脚本。然而,作为一个特殊的例外,分发的源代码不需要包含与运行可执行文件的操作系统的主要组件(编译器、内核等)正常分发的任何内容(以源代码或二进制形式),除非该组件本身附带可执行文件。
如果通过提供从指定位置复制源代码的访问权限来分发可执行代码或目标代码,则提供从同一位置复制源代码的同等访问权限也算作源代码的分发,即使第三方不被迫复制源代码源代码和目标代码。
You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
除非本许可证明确规定,否则您不得复制、修改、再许可或分发本程序。任何以其他方式复制、修改、再许可或分发本程序的尝试均无效,并将自动终止您在本许可下的权利。但是,根据本许可证从您那里收到副本或权利的各方只要完全遵守规定,其许可证就不会被终止。
You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
您无需接受本许可证,因为您尚未签署。但是,没有其他任何内容授予您修改或分发本程序或其衍生作品的权限。如果您不接受本许可,这些行为将受到法律禁止。因此,通过修改或分发本程序(或基于本程序的任何作品),即表示您接受本许可,以及复制、分发或修改本程序或基于本程序的作品的所有条款和条件。
You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
每次重新分发本程序(或基于本程序的任何作品)时,接收者都会自动收到原始许可方的许可,以便根据这些条款和条件复制、分发或修改本程序。您不得对接收者行使此处授予的权利施加任何进一步的限制。您不负责强制第三方遵守本许可证。
Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
如果由于法院判决或专利侵权指控或任何其他原因(不限于专利问题),对您施加了与本许可条件相矛盾的条件(无论是通过法院命令、协议还是其他方式),他们不会免除您遵守本许可证的条件。如果您无法通过分发来同时履行您在本许可下的义务和任何其他相关义务,那么您可能根本无法分发该程序。例如,如果专利许可不允许所有直接或间接通过您接收副本的人免版税地重新分发本程序,那么您满足专利许可和本许可的唯一方法就是完全避免分发该程序。程序。
如果本节的任何部分在任何特定情况下被视为无效或无法执行,则该节的其余部分将适用,并且该节作为一个整体将适用于其他情况。
本节的目的不是诱导您侵犯任何专利或其他产权主张或质疑任何此类主张的有效性;本节的唯一目的是保护通过公共许可实践实施的自由软件分发系统的完整性。许多人依赖于该系统的一致应用,为通过该系统分发的各种软件做出了慷慨的贡献;由作者/捐赠者决定他或她是否愿意通过任何其他系统分发软件,被许可人不能强加这种选择。
本节旨在彻底阐明本许可证其余部分的后果。
如果程序的分发和/或使用在某些国家/地区受到专利或受版权保护的接口的限制,则将程序置于本许可证之下的原始版权所有者可以添加明确的地理分发限制,排除这些国家/地区,以便允许分发仅在未被排除在外的国家内或之间。在这种情况下,本许可证包含该限制,就像写入本许可证正文一样。
If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
自由软件基金会可能会不时发布通用公共许可证的修订版和/或新版本。此类新版本在精神上与当前版本相似,但在解决新问题或疑虑方面可能在细节上有所不同。
每一个版本都有不同的版本号。如果本程序指定了适用于它的本许可证的版本号和“任何更高版本”,则您可以选择遵循该版本或自由软件基金会发布的任何更高版本的条款和条件。如果本程序未指定本许可证的版本号,您可以选择自由软件基金会曾经发布的任何版本。
The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
如果您希望将本程序的部分内容合并到分发条件不同的其他免费程序中,请写信给作者以请求许可。对于自由软件基金会拥有版权的软件,请写信给自由软件基金会;我们有时会对此做出例外处理。我们的决定将遵循两个目标:维护我们的自由软件所有衍生品的自由状态以及促进软件的共享和重用。
If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
没有保修
由于该程序是免费许可的,因此在适用法律允许的范围内,对该程序不提供任何保证。除非另有书面说明,版权所有者和/或其他方“按原样”提供程序,不提供任何类型的明示或默示保证,包括但不限于适销性和特定用途适用性的默示保证。本计划的质量和性能的全部风险由您承担。如果该程序被证明有缺陷,您将承担所有必要的维修、修理或纠正的费用。
NO WARRANTY
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
在任何情况下,除非适用法律要求或书面同意,否则任何版权持有者或可能修改和/或重新分发上述允许的程序的任何其他方均不对您的损害承担责任,包括任何一般、特殊、附带或损害因使用或无法使用本程序而造成的间接损害(包括但不限于数据丢失或数据不准确或由您或第三方承受的损失或本程序无法与任何其他程序一起运行),甚至如果此类持有人或其他方已被告知发生此类损害的可能性。
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
条款和条件结束
END OF TERMS AND CONDITIONS
如果您开发一个新程序,并且希望它对公众有最大的用途,那么实现这一目标的最佳方法是使其成为免费软件,每个人都可以根据这些条款重新分发和更改。
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
为此,请将以下通知附加到程序中。最安全的做法是将它们附加到每个源文件的开头,以最有效地表达保修的排除;每个文件至少应该有“版权”行和一个指向完整通知位置的指针。
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<一行给出程序的名称和其功能的简要说明。> 版权所有 (C) <年份> <作者姓名>该程序是免费软件;您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改它;许可证的版本 2,或(由您选择)任何更高版本。
分发此程序的目的是希望它有用,但不提供任何保证;甚至没有适销性或特定用途适用性的默示保证。有关更多详细信息,请参阅 GNU 通用公共许可证。
您应该随该程序一起收到 GNU 通用公共许可证的副本;如果没有,请写信给 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
另请添加有关如何通过电子邮件和纸质邮件与您联系的信息。
Also add information on how to contact you by electronic and paper mail.
如果程序是交互式的,当它以交互模式启动时,让它输出一个简短的通知:
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision 版本 69,版权所有 (C) 作者姓名 Gnomovision 不附带任何保证;有关详细信息,请输入“show w”。这是免费软件,欢迎您在一定条件下重新分发它;输入“show c”了解详细信息。
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
假设的命令“show w”和“show c”应该显示通用公共许可证的适当部分。当然,您使用的命令可能被称为“show w”和“show c”以外的名称;它们甚至可以是鼠标点击或菜单项——只要适合您的程序即可。
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
如有必要,您还应该让您的雇主(如果您是程序员)或您的学校(如果有)签署该程序的“版权免责声明”。这是一个示例;更改名称:
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc. 特此声明放弃 James Hacker 编写的程序“Gnomovision”(在编译器中进行传递)的所有版权利益。<Ty Coon 签名>,1989 年 4 月 1 日 Ty Coon,副总裁
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice
本通用公共许可证不允许将您的程序合并到专有程序中。如果您的程序是子例程库,您可能会认为允许将专有应用程序与该库链接更有用。如果您想要这样做,请使用 GNU 库通用公共许可证而不是本许可证。
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
#!/bin/sh
#
# rc.firewall - 适用于 Linux 2.4.x 和 iptables 的初始简单 IP 防火墙脚本
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
#################################################### ##########################
#
# 1.配置选项。
#
#
# 1.1 互联网配置。
#
INET_IP =“194.236.50.155”
INET_IFACE=“eth0”
INET_BROADCAST =“194.236.50.255”
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 局域网配置。
#
# 你的 LAN 的 IP 范围和本地主机 IP。/24 表示仅使用前 24 位
32 位 IP 地址的 # 位。与网络掩码 255.255.255.0 相同
#
LAN_IP=“192.168.0.2”
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE=“eth1”
#
# 1.3 DMZ 配置。
#
#
# 1.4 本地主机配置。
#
LO_IFACE="洛"
LO_IP="127.0.0.1"
#
# 1.5 IPTables 配置。
#
IPTABLES =“/ usr / sbin / iptables”
#
# 1.6 其他配置。
#
#################################################### ##########################
#
# 2.模块加载。
#
#
# 需要初始加载模块
#
/sbin/depmod -a
#
# 2.1 所需模块
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 非必需模块
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
#################################################### ##########################
#
# 3. /proc 设置。
#
#
# 3.1 所需的proc配置
#
回声“1”> / proc / sys / net / ipv4 / ip_forward
#
# 3.2 非必需的proc配置
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo“1”> /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
#################################################### ##########################
#
#4.规则设置。
#
######
# 4.1 过滤表
#
#
# 4.1.1 设置策略
#
$IPTABLES -P 输入丢弃
$IPTABLES -P 输出下降
$IPTABLES -P 前向丢弃
#
# 4.1.2 创建用户指定链
#
#
# 为坏的 tcp 数据包创建链
#
$IPTABLES -N bad_tcp_packets
#
# 创建单独的链供 ICMP、TCP 和 UDP 遍历
#
$IPTABLES -N 允许
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 在用户指定的链中创建内容
#
#
# bad_tcp_packets 链
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m 状态 --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 日志 \
--log-prefix "新的不是 syn:"
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 删除
#
# 允许的链
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A 允许 -p TCP -j DROP
#
# TCP 规则
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j 允许
#
# UDP端口
#
#$IPTABLES -A udp_packets -p UDP -s 0/0 --目标端口 53 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --目标端口 123 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --目标端口 2074 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --目标端口 4000 -j 接受
#
# 在 Microsoft 网络中,您将被广播淹没。这些行
# 将阻止它们出现在日志中。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--目标端口 135:139 -j 删除
#
# 如果我们从网络外部收到 DHCP 请求,我们的日志将
# 也被淹没。此规则将阻止他们被记录。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--目标端口 67:68 -j 删除
#
# ICMP 规则
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j 接受
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp 类型 11 -j 接受
#
# 4.1.4 INPUT链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输入 -p tcp -j bad_tcp_packets
#
# 不属于互联网一部分的特殊网络的规则
#
$IPTABLES -A 输入 -p 全部 -i $LAN_IFACE -s $LAN_IP_RANGE -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LO_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LAN_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $INET_IP -j 接受
#
# 来自 LAN 的 DHCP 请求的特殊规则,未正确捕获
# 否则。
#
$IPTABLES -A 输入 -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j 接受
#
# 来自互联网的传入数据包的规则。
#
$IPTABLES -A 输入 -p 全部 -d $INET_IP -m 状态 --state 已建立,相关 \
-j 接受
$IPTABLES -A 输入 -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A 输入 -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A 输入 -p ICMP -i $INET_IFACE -j icmp_packets
#
# 如果您的防火墙外部有 Microsoft 网络,您可以
# 也会被多播淹没。我们丢弃它们,这样我们就不会被淹没
# 日志
#
#$IPTABLES -A 输入 -i $INET_IFACE -d 224.0.0.0/8 -j 删除
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A INPUT -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT 数据包死亡:"
#
# 4.1.5 FORWARD链
#
#
# 我们不想要的坏 TCP 数据包
#
$IPTABLES -A 转发 -p tcp -j bad_tcp_packets
#
# 接受我们真正想要转发的数据包
#
$IPTABLES -A 转发 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -m 状态 --state 已建立,相关 -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A FORWARD -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD 数据包死亡:"
#
# 4.1.6 输出链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输出 -p tcp -j bad_tcp_packets
#
# 特殊的输出规则来决定允许哪些IP。
#
$IPTABLES -A 输出 -p 全部 -s $LO_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $LAN_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $INET_IP -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A 输出 -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT 数据包已死亡:"
######
# 4.2 nat表
#
#
# 4.2.1 设置策略
#
#
# 4.2.2 创建用户指定链
#
#
# 4.2.3 在用户指定链中创建内容
#
#
# 4.2.4 PREROUTING链
#
#
# 4.2.5 POSTROUTING链
#
#
# 启用简单IP转发和网络地址转换
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 输出链
#
######
# 4.3 变形表
#
#
# 4.3.1 设置策略
#
#
# 4.3.2 创建用户指定链
#
#
# 4.3.3 在用户指定链中创建内容
#
#
# 4.3.4 PREROUTING链
#
#
# 4.3.5 INPUT链
#
#
# 4.3.6 FORWARD链
#
#
# 4.3.7 输出链
#
#
# 4.3.8 POSTROUTING链
#
#!/bin/sh
#
# rc.firewall - Initial SIMPLE IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
###########################################################################
#
# 1. Configuration options.
#
#
# 1.1 Internet Configuration.
#
INET_IP="194.236.50.155"
INET_IFACE="eth0"
INET_BROADCAST="194.236.50.255"
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#
LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"
#
# 1.3 DMZ Configuration.
#
#
# 1.4 Localhost Configuration.
#
LO_IFACE="lo"
LO_IP="127.0.0.1"
#
# 1.5 IPTables Configuration.
#
IPTABLES="/usr/sbin/iptables"
#
# 1.6 Other Configuration.
#
###########################################################################
#
# 2. Module loading.
#
#
# Needed to initially load modules
#
/sbin/depmod -a
#
# 2.1 Required modules
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 Non-Required modules
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
###########################################################################
#
# 3. /proc set up.
#
#
# 3.1 Required proc configuration
#
echo "1" > /proc/sys/net/ipv4/ip_forward
#
# 3.2 Non-Required proc configuration
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
###########################################################################
#
# 4. rules set up.
#
######
# 4.1 Filter table
#
#
# 4.1.1 Set policies
#
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
#
# 4.1.2 Create userspecified chains
#
#
# Create chain for bad tcp packets
#
$IPTABLES -N bad_tcp_packets
#
# Create separate chains for ICMP, TCP and UDP to traverse
#
$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 Create content in userspecified chains
#
#
# bad_tcp_packets chain
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
#
# allowed chain
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP
#
# TCP rules
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed
#
# UDP ports
#
#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 123 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 2074 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 4000 -j ACCEPT
#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP
#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP
#
# ICMP rules
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
#
# 4.1.4 INPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
#
# Rules for special networks not part of the Internet
#
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT
#
# Special rule for DHCP requests from LAN, which are not caught properly
# otherwise.
#
$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT
#
# Rules for incoming packets from the internet.
#
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#
#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP
#
# Log weird packets that don't match the above.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "
#
# 4.1.5 FORWARD chain
#
#
# Bad TCP packets we don't want
#
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
#
# Accept the packets we actually want to forward
#
$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "
#
# 4.1.6 OUTPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
#
# Special OUTPUT rules to decide which IP's to allow.
#
$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
######
# 4.2 nat table
#
#
# 4.2.1 Set policies
#
#
# 4.2.2 Create user specified chains
#
#
# 4.2.3 Create content in user specified chains
#
#
# 4.2.4 PREROUTING chain
#
#
# 4.2.5 POSTROUTING chain
#
#
# Enable simple IP Forwarding and Network Address Translation
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 OUTPUT chain
#
######
# 4.3 mangle table
#
#
# 4.3.1 Set policies
#
#
# 4.3.2 Create user specified chains
#
#
# 4.3.3 Create content in user specified chains
#
#
# 4.3.4 PREROUTING chain
#
#
# 4.3.5 INPUT chain
#
#
# 4.3.6 FORWARD chain
#
#
# 4.3.7 OUTPUT chain
#
#
# 4.3.8 POSTROUTING chain
#
#!/bin/sh
#
# rc.DMZ.firewall - 适用于 Linux 2.4.x 和 iptables 的 DMZ IP 防火墙脚本
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
#################################################### ##########################
#
# 1.配置选项。
#
#
# 1.1 互联网配置。
#
INET_IP =“194.236.50.152”
HTTP_IP =“194.236.50.153”
DNS_IP =“194.236.50.154”
INET_IFACE=“eth0”
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 局域网配置。
#
# 你的 LAN 的 IP 范围和本地主机 IP。/24 表示仅使用前 24 位
32 位 IP 地址的 # 位。与网络掩码 255.255.255.0 相同
#
LAN_IP=“192.168.0.1”
LAN_IFACE=“eth1”
#
# 1.3 DMZ 配置。
#
DMZ_HTTP_IP =“192.168.1.2”
DMZ_DNS_IP =“192.168.1.3”
DMZ_IP =“192.168.1.1”
DMZ_IFACE=“eth2”
#
# 1.4 本地主机配置。
#
LO_IFACE="洛"
LO_IP="127.0.0.1"
#
# 1.5 IPTables 配置。
#
IPTABLES =“/ usr / sbin / iptables”
#
# 1.6 其他配置。
#
#################################################### ##########################
#
# 2.模块加载。
#
#
# 需要初始加载模块
#
/sbin/depmod -a
#
# 2.1 所需模块
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 非必需模块
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
#################################################### ##########################
#
# 3. /proc 设置。
#
#
# 3.1 所需的proc配置
#
回声“1”> / proc / sys / net / ipv4 / ip_forward
#
# 3.2 非必需的proc配置
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo“1”> /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
#################################################### ##########################
#
#4.规则设置。
#
######
# 4.1 过滤表
#
#
# 4.1.1 设置策略
#
$IPTABLES -P 输入丢弃
$IPTABLES -P 输出下降
$IPTABLES -P 前向丢弃
#
# 4.1.2 创建用户指定链
#
#
# 为坏的 tcp 数据包创建链
#
$IPTABLES -N bad_tcp_packets
#
# 创建单独的链供 ICMP、TCP 和 UDP 遍历
#
$IPTABLES -N 允许
$IPTABLES -N icmp_packets
#
# 4.1.3 在用户指定的链中创建内容
#
#
# bad_tcp_packets 链
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m 状态 --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 日志 \
--log-prefix "新的不是 syn:"
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 删除
#
# 允许的链
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A 允许 -p TCP -j DROP
#
# ICMP 规则
#
# 完全改变了规则
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j 接受
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp 类型 11 -j 接受
#
# 4.1.4 INPUT链
#
#
# 我们不想要的坏 TCP 数据包
#
$IPTABLES -A 输入 -p tcp -j bad_tcp_packets
#
# 从互联网到此盒子的数据包
#
$IPTABLES -A 输入 -p ICMP -i $INET_IFACE -j icmp_packets
#
# 来自 LAN、DMZ 或 LOCALHOST 的数据包
#
#
# 从 DMZ 接口到 DMZ 防火墙 IP
#
$IPTABLES -A 输入 -p 全部 -i $DMZ_IFACE -d $DMZ_IP -j 接受
#
# 从 LAN 接口到 LAN 防火墙 IP
#
$IPTABLES -A 输入 -p 全部 -i $LAN_IFACE -d $LAN_IP -j 接受
#
# 从本地主机接口到本地主机IP
#
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LO_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LAN_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $INET_IP -j 接受
#
# 来自 LAN 的 DHCP 请求的特殊规则,未正确捕获
# 否则。
#
$IPTABLES -A 输入 -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j 接受
#
# 所有已建立的相关数据包从互联网传入
# 防火墙
#
$IPTABLES -A 输入 -p 全部 -d $INET_IP -m 状态 --state 已建立,相关 \
-j 接受
#
# 在 Microsoft 网络中,您将被广播淹没。这些行
# 将阻止它们出现在日志中。
#
#$IPTABLES -A 输入 -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--目标端口 135:139 -j 删除
#
# 如果我们从网络外部收到 DHCP 请求,我们的日志将
# 也被淹没。此规则将阻止他们被记录。
#
#$IPTABLES -A 输入 -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--目标端口 67:68 -j 删除
#
# 如果您的防火墙外部有 Microsoft 网络,您可以
# 也会被多播淹没。我们丢弃它们,这样我们就不会被淹没
# 日志
#
#$IPTABLES -A 输入 -i $INET_IFACE -d 224.0.0.0/8 -j 删除
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A INPUT -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT 数据包死亡:"
#
# 4.1.5 FORWARD链
#
#
# 我们不想要的坏 TCP 数据包
#
$IPTABLES -A 转发 -p tcp -j bad_tcp_packets
#
# DMZ 部分
#
# 一般规则
#
$IPTABLES -A 转发 -i $DMZ_IFACE -o $INET_IFACE -j 接受
$IPTABLES -A FORWARD -i $INET_IFACE -o $DMZ_IFACE -m 状态 \
--state 已建立,相关 -j 接受
$IPTABLES -A 转发 -i $LAN_IFACE -o $DMZ_IFACE -j 接受
$IPTABLES -A FORWARD -i $DMZ_IFACE -o $LAN_IFACE -m 状态 \
--state 已建立,相关 -j 接受
#
# HTTP 服务器
#
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
--dport 80 -j 允许
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
-j icmp_数据包
#
# DNS服务器
#
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j 允许
$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j 接受
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
-j icmp_数据包
#
# 局域网部分
#
$IPTABLES -A 转发 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -m 状态 --state 已建立,相关 -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A FORWARD -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD 数据包死亡:"
#
# 4.1.6 输出链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输出 -p tcp -j bad_tcp_packets
#
# 特殊的输出规则来决定允许哪些IP。
#
$IPTABLES -A 输出 -p 全部 -s $LO_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $LAN_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $INET_IP -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A 输出 -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT 数据包已死亡:"
######
# 4.2 nat表
#
#
# 4.2.1 设置策略
#
#
# 4.2.2 创建用户指定链
#
#
# 4.2.3 在用户指定链中创建内容
#
#
# 4.2.4 PREROUTING链
#
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $HTTP_IP --dport 80 \
-j DNAT --到目的地 $DMZ_HTTP_IP
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --到目的地 $DMZ_DNS_IP
$IPTABLES -t nat -A PREROUTING -p UDP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --到目的地 $DMZ_DNS_IP
#
# 4.2.5 POSTROUTING链
#
#
# 启用简单IP转发和网络地址转换
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 输出链
#
######
# 4.3 变形表
#
#
# 4.3.1 设置策略
#
#
# 4.3.2 创建用户指定链
#
#
# 4.3.3 在用户指定链中创建内容
#
#
# 4.3.4 PREROUTING链
#
#
# 4.3.5 INPUT链
#
#
# 4.3.6 FORWARD链
#
#
# 4.3.7 输出链
#
#
# 4.3.8 POSTROUTING链
#
#!/bin/sh
#
# rc.DMZ.firewall - DMZ IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
###########################################################################
#
# 1. Configuration options.
#
#
# 1.1 Internet Configuration.
#
INET_IP="194.236.50.152"
HTTP_IP="194.236.50.153"
DNS_IP="194.236.50.154"
INET_IFACE="eth0"
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#
LAN_IP="192.168.0.1"
LAN_IFACE="eth1"
#
# 1.3 DMZ Configuration.
#
DMZ_HTTP_IP="192.168.1.2"
DMZ_DNS_IP="192.168.1.3"
DMZ_IP="192.168.1.1"
DMZ_IFACE="eth2"
#
# 1.4 Localhost Configuration.
#
LO_IFACE="lo"
LO_IP="127.0.0.1"
#
# 1.5 IPTables Configuration.
#
IPTABLES="/usr/sbin/iptables"
#
# 1.6 Other Configuration.
#
###########################################################################
#
# 2. Module loading.
#
#
# Needed to initially load modules
#
/sbin/depmod -a
#
# 2.1 Required modules
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 Non-Required modules
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
###########################################################################
#
# 3. /proc set up.
#
#
# 3.1 Required proc configuration
#
echo "1" > /proc/sys/net/ipv4/ip_forward
#
# 3.2 Non-Required proc configuration
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
###########################################################################
#
# 4. rules set up.
#
######
# 4.1 Filter table
#
#
# 4.1.1 Set policies
#
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
#
# 4.1.2 Create userspecified chains
#
#
# Create chain for bad tcp packets
#
$IPTABLES -N bad_tcp_packets
#
# Create separate chains for ICMP, TCP and UDP to traverse
#
$IPTABLES -N allowed
$IPTABLES -N icmp_packets
#
# 4.1.3 Create content in userspecified chains
#
#
# bad_tcp_packets chain
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
#
# allowed chain
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP
#
# ICMP rules
#
# Changed rules totally
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
#
# 4.1.4 INPUT chain
#
#
# Bad TCP packets we don't want
#
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
#
# Packets from the Internet to this box
#
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
#
# Packets from LAN, DMZ or LOCALHOST
#
#
# From DMZ Interface to DMZ firewall IP
#
$IPTABLES -A INPUT -p ALL -i $DMZ_IFACE -d $DMZ_IP -j ACCEPT
#
# From LAN Interface to LAN firewall IP
#
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_IP -j ACCEPT
#
# From Localhost interface to Localhost IP's
#
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT
#
# Special rule for DHCP requests from LAN, which are not caught properly
# otherwise.
#
$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT
#
# All established and related packets incoming from the internet to the
# firewall
#
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#
#$IPTABLES -A INPUT -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP
#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#
#$IPTABLES -A INPUT -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP
#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#
#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP
#
# Log weird packets that don't match the above.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "
#
# 4.1.5 FORWARD chain
#
#
# Bad TCP packets we don't want
#
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
#
# DMZ section
#
# General rules
#
$IPTABLES -A FORWARD -i $DMZ_IFACE -o $INET_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -o $DMZ_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -o $DMZ_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $DMZ_IFACE -o $LAN_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT
#
# HTTP server
#
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
--dport 80 -j allowed
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
-j icmp_packets
#
# DNS server
#
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j allowed
$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j ACCEPT
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
-j icmp_packets
#
# LAN section
#
$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "
#
# 4.1.6 OUTPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
#
# Special OUTPUT rules to decide which IP's to allow.
#
$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
######
# 4.2 nat table
#
#
# 4.2.1 Set policies
#
#
# 4.2.2 Create user specified chains
#
#
# 4.2.3 Create content in user specified chains
#
#
# 4.2.4 PREROUTING chain
#
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $HTTP_IP --dport 80 \
-j DNAT --to-destination $DMZ_HTTP_IP
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --to-destination $DMZ_DNS_IP
$IPTABLES -t nat -A PREROUTING -p UDP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --to-destination $DMZ_DNS_IP
#
# 4.2.5 POSTROUTING chain
#
#
# Enable simple IP Forwarding and Network Address Translation
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 OUTPUT chain
#
######
# 4.3 mangle table
#
#
# 4.3.1 Set policies
#
#
# 4.3.2 Create user specified chains
#
#
# 4.3.3 Create content in user specified chains
#
#
# 4.3.4 PREROUTING chain
#
#
# 4.3.5 INPUT chain
#
#
# 4.3.6 FORWARD chain
#
#
# 4.3.7 OUTPUT chain
#
#
# 4.3.8 POSTROUTING chain
#
#!/bin/sh
#
# rc.UTIN.firewall - 适用于 Linux 2.4.x 和 iptables 的 UTIN 防火墙脚本
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
#################################################### ##########################
#
# 1.配置选项。
#
#
# 1.1 互联网配置。
#
INET_IP =“194.236.50.155”
INET_IFACE=“eth0”
INET_BROADCAST =“194.236.50.255”
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 局域网配置。
#
# 你的 LAN 的 IP 范围和本地主机 IP。/24 表示仅使用前 24 位
32 位 IP 地址的 # 位。与网络掩码 255.255.255.0 相同
#
LAN_IP=“192.168.0.2”
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE=“eth1”
#
# 1.3 DMZ 配置。
#
#
# 1.4 本地主机配置。
#
LO_IFACE="洛"
LO_IP="127.0.0.1"
#
# 1.5 IPTables 配置。
#
IPTABLES =“/ usr / sbin / iptables”
#
# 1.6 其他配置。
#
#################################################### ##########################
#
# 2.模块加载。
#
#
# 需要初始加载模块
#
/sbin/depmod -a
#
# 2.1 所需模块
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 非必需模块
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
#################################################### ##########################
#
# 3. /proc 设置。
#
#
# 3.1 所需的proc配置
#
回声“1”> / proc / sys / net / ipv4 / ip_forward
#
# 3.2 非必需的proc配置
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo“1”> /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
#################################################### ##########################
#
#4.规则设置。
#
######
# 4.1 过滤表
#
#
# 4.1.1 设置策略
#
$IPTABLES -P 输入丢弃
$IPTABLES -P 输出下降
$IPTABLES -P 前向丢弃
#
# 4.1.2 创建用户指定链
#
#
# 为坏的 tcp 数据包创建链
#
$IPTABLES -N bad_tcp_packets
#
# 创建单独的链供 ICMP、TCP 和 UDP 遍历
#
$IPTABLES -N 允许
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 在用户指定的链中创建内容
#
#
# bad_tcp_packets 链
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m 状态 --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 日志 \
--log-prefix "新的不是 syn:"
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 删除
#
# 允许的链
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A 允许 -p TCP -j DROP
#
# TCP 规则
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j 允许
#
# UDP端口
#
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 53 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 123 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 2074 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 4000 -j 接受
#
# 在 Microsoft 网络中,您将被广播淹没。这些行
# 将阻止它们出现在日志中。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--目标端口 135:139 -j 删除
#
# 如果我们从网络外部收到 DHCP 请求,我们的日志将
# 也被淹没。此规则将阻止他们被记录。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--目标端口 67:68 -j 删除
#
# ICMP 规则
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j 接受
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp 类型 11 -j 接受
#
# 4.1.4 INPUT链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输入 -p tcp -j bad_tcp_packets
#
# 不属于互联网一部分的特殊网络的规则
#
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LO_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $LAN_IP -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -s $INET_IP -j 接受
#
# 来自任何地方的传入数据包的规则。
#
$IPTABLES -A 输入 -p 全部 -d $INET_IP -m 状态 --state 已建立,相关 \
-j 接受
$IPTABLES -A 输入 -p TCP -j tcp_packets
$IPTABLES -A 输入 -p UDP -j udp_packets
$IPTABLES -A 输入 -p ICMP -j icmp_packets
#
# 如果您的防火墙外部有 Microsoft 网络,您可以
# 也会被多播淹没。我们丢弃它们,这样我们就不会被淹没
# 日志
#
#$IPTABLES -A 输入 -i $INET_IFACE -d 224.0.0.0/8 -j 删除
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A INPUT -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT 数据包死亡:"
#
# 4.1.5 FORWARD链
#
#
# 我们不想要的坏 TCP 数据包
#
$IPTABLES -A 转发 -p tcp -j bad_tcp_packets
#
# 接受我们真正想要转发的数据包
#
$IPTABLES -A 转发 -p tcp --dport 21 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -p tcp --dport 80 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -p tcp --dport 110 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -m 状态 --state 已建立,相关 -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A FORWARD -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD 数据包死亡:"
#
# 4.1.6 输出链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输出 -p tcp -j bad_tcp_packets
#
# 特殊的输出规则来决定允许哪些IP。
#
$IPTABLES -A 输出 -p 全部 -s $LO_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $LAN_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $INET_IP -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A 输出 -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT 数据包已死亡:"
######
# 4.2 nat表
#
#
# 4.2.1 设置策略
#
#
# 4.2.2 创建用户指定链
#
#
# 4.2.3 在用户指定链中创建内容
#
#
# 4.2.4 PREROUTING链
#
#
# 4.2.5 POSTROUTING链
#
#
# 启用简单IP转发和网络地址转换
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 输出链
#
######
# 4.3 变形表
#
#
# 4.3.1 设置策略
#
#
# 4.3.2 创建用户指定链
#
#
# 4.3.3 在用户指定链中创建内容
#
#
# 4.3.4 PREROUTING链
#
#
# 4.3.5 INPUT链
#
#
# 4.3.6 FORWARD链
#
#
# 4.3.7 输出链
#
#
# 4.3.8 POSTROUTING链
#
#!/bin/sh
#
# rc.UTIN.firewall - UTIN Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
###########################################################################
#
# 1. Configuration options.
#
#
# 1.1 Internet Configuration.
#
INET_IP="194.236.50.155"
INET_IFACE="eth0"
INET_BROADCAST="194.236.50.255"
#
# 1.1.1 DHCP
#
#
# 1.1.2 PPPoE
#
#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#
LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"
#
# 1.3 DMZ Configuration.
#
#
# 1.4 Localhost Configuration.
#
LO_IFACE="lo"
LO_IP="127.0.0.1"
#
# 1.5 IPTables Configuration.
#
IPTABLES="/usr/sbin/iptables"
#
# 1.6 Other Configuration.
#
###########################################################################
#
# 2. Module loading.
#
#
# Needed to initially load modules
#
/sbin/depmod -a
#
# 2.1 Required modules
#
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
#
# 2.2 Non-Required modules
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
###########################################################################
#
# 3. /proc set up.
#
#
# 3.1 Required proc configuration
#
echo "1" > /proc/sys/net/ipv4/ip_forward
#
# 3.2 Non-Required proc configuration
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
###########################################################################
#
# 4. rules set up.
#
######
# 4.1 Filter table
#
#
# 4.1.1 Set policies
#
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
#
# 4.1.2 Create userspecified chains
#
#
# Create chain for bad tcp packets
#
$IPTABLES -N bad_tcp_packets
#
# Create separate chains for ICMP, TCP and UDP to traverse
#
$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 Create content in userspecified chains
#
#
# bad_tcp_packets chain
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
#
# allowed chain
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP
#
# TCP rules
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed
#
# UDP ports
#
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT
#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP
#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP
#
# ICMP rules
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
#
# 4.1.4 INPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
#
# Rules for special networks not part of the Internet
#
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT
#
# Rules for incoming packets from anywhere.
#
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -j tcp_packets
$IPTABLES -A INPUT -p UDP -j udp_packets
$IPTABLES -A INPUT -p ICMP -j icmp_packets
#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#
#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP
#
# Log weird packets that don't match the above.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "
#
# 4.1.5 FORWARD chain
#
#
# Bad TCP packets we don't want
#
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
#
# Accept the packets we actually want to forward
#
$IPTABLES -A FORWARD -p tcp --dport 21 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 80 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 110 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "
#
# 4.1.6 OUTPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
#
# Special OUTPUT rules to decide which IP's to allow.
#
$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
######
# 4.2 nat table
#
#
# 4.2.1 Set policies
#
#
# 4.2.2 Create user specified chains
#
#
# 4.2.3 Create content in user specified chains
#
#
# 4.2.4 PREROUTING chain
#
#
# 4.2.5 POSTROUTING chain
#
#
# Enable simple IP Forwarding and Network Address Translation
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
#
# 4.2.6 OUTPUT chain
#
######
# 4.3 mangle table
#
#
# 4.3.1 Set policies
#
#
# 4.3.2 Create user specified chains
#
#
# 4.3.3 Create content in user specified chains
#
#
# 4.3.4 PREROUTING chain
#
#
# 4.3.5 INPUT chain
#
#
# 4.3.6 FORWARD chain
#
#
# 4.3.7 OUTPUT chain
#
#
# 4.3.8 POSTROUTING chain
#
#!/bin/sh
#
# rc.DHCP.firewall - 适用于 Linux 2.4.x 和 iptables 的 DHCP IP 防火墙脚本
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
#################################################### ##########################
#
# 1.配置选项。
#
#
# 1.1 互联网配置。
#
INET_IFACE=“eth0”
#
# 1.1.1 DHCP
#
#
# 有关 Internet 上 DHCP 的信息(如果需要)。
#
# 如果您没有从 DHCP 获取 IP,请将 DHCP 变量设置为 no。如果您获得 DHCP
# 通过 Internet 将此变量设置为 yes,并设置正确的 IP
# DHCP_SERVER 变量中的 DHCP 服务器地址。
#
DHCP=“否”
DHCP_SERVER =“195.22.90.65”
#
# 1.1.2 PPPoE
#
# 与 PPPoE 相关的配置选项。
#
# 如果您的 PPPoE 连接有问题,例如大邮件则无法
# 打通小邮件是否正常打通等,您可以设置
# 将此选项设置为“yes”,这可能会解决问题。该选项将设置一个
# 将夹紧的 mangle 表的 PREROUTING 链中的规则
# 将所有路由数据包调整为 PMTU(路径最大传输单元)。
#
# 请注意,最好在 PPPoE 包本身中进行设置,因为
# PPPoE 配置选项将提供更少的开销。
#
PPPOE_PMTU="否"
#
# 1.2 局域网配置。
#
# 你的 LAN 的 IP 范围和本地主机 IP。/24 表示仅使用前 24 位
32 位 IP 地址的 # 位。与网络掩码 255.255.255.0 相同
#
LAN_IP=“192.168.0.2”
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE=“eth1”
#
# 1.3 DMZ 配置。
#
#
# 1.4 本地主机配置。
#
LO_IFACE="洛"
LO_IP="127.0.0.1"
#
# 1.5 IPTables 配置。
#
IPTABLES =“/ usr / sbin / iptables”
#
# 1.6 其他配置。
#
#################################################### ##########################
#
# 2.模块加载。
#
#
# 需要初始加载模块
#
/sbin/depmod -a
#
# 2.1 所需模块
#
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_tables
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_MASQUERADE
#
# 2.2 非必需模块
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
#################################################### ##########################
#
# 3. /proc 设置。
#
#
# 3.1 所需的proc配置
#
回声“1”> / proc / sys / net / ipv4 / ip_forward
#
# 3.2 非必需的proc配置
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo“1”> /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
#################################################### ##########################
#
#4.规则设置。
#
######
# 4.1 过滤表
#
#
# 4.1.1 设置策略
#
$IPTABLES -P 输入丢弃
$IPTABLES -P 输出下降
$IPTABLES -P 前向丢弃
#
# 4.1.2 创建用户指定链
#
#
# 为坏的 tcp 数据包创建链
#
$IPTABLES -N bad_tcp_packets
#
# 创建单独的链供 ICMP、TCP 和 UDP 遍历
#
$IPTABLES -N 允许
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 在用户指定的链中创建内容
#
#
# bad_tcp_packets 链
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m 状态 --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 日志 \
--log-prefix "新的不是 syn:"
$IPTABLES -A bad_tcp_packets -p tcp !--syn -m 状态 --state 新-j 删除
#
# 允许的链
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A 允许 -p TCP -j DROP
#
# TCP 规则
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j 允许
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j 允许
#
# UDP端口
#
$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 53 -j 接受
如果 [ $DHCP == "是" ] ; 然后
$IPTABLES -A udp_packets -p UDP -s $DHCP_SERVER --sport 67 \
--dport 68 -j 接受
菲
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 53 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 123 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 2074 -j 接受
#$IPTABLES -A udp_packets -p UDP -s 0/0 --源端口 4000 -j 接受
#
# 在 Microsoft 网络中,您将被广播淹没。这些行
# 将阻止它们出现在日志中。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE \
#--目标端口 135:139 -j 删除
#
# 如果我们从网络外部收到 DHCP 请求,我们的日志将
# 也被淹没。此规则将阻止他们被记录。
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--目标端口 67:68 -j 删除
#
# ICMP 规则
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j 接受
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp 类型 11 -j 接受
#
# 4.1.4 INPUT链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输入 -p tcp -j bad_tcp_packets
#
# 不属于互联网一部分的特殊网络的规则
#
$IPTABLES -A 输入 -p 全部 -i $LAN_IFACE -s $LAN_IP_RANGE -j 接受
$IPTABLES -A 输入 -p 全部 -i $LO_IFACE -j 接受
#
# 来自 LAN 的 DHCP 请求的特殊规则,未正确捕获
# 否则。
#
$IPTABLES -A 输入 -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j 接受
#
# 来自互联网的传入数据包的规则。
#
$IPTABLES -A 输入 -p 全部 -i $INET_IFACE -m 状态 --state 已建立,相关 \
-j 接受
$IPTABLES -A 输入 -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A 输入 -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A 输入 -p ICMP -i $INET_IFACE -j icmp_packets
#
# 如果您的防火墙外部有 Microsoft 网络,您可以
# 也会被多播淹没。我们丢弃它们,这样我们就不会被淹没
# 日志
#
#$IPTABLES -A 输入 -i $INET_IFACE -d 224.0.0.0/8 -j 删除
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A INPUT -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT 数据包死亡:"
#
# 4.1.5 FORWARD链
#
#
# 我们不想要的坏 TCP 数据包
#
$IPTABLES -A 转发 -p tcp -j bad_tcp_packets
#
# 接受我们真正想要转发的数据包
#
$IPTABLES -A 转发 -i $LAN_IFACE -j 接受
$IPTABLES -A 转发 -m 状态 --state 已建立,相关 -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A FORWARD -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD 数据包死亡:"
#
# 4.1.6 输出链
#
#
# 我们不想要坏的 TCP 数据包。
#
$IPTABLES -A 输出 -p tcp -j bad_tcp_packets
#
# 特殊的输出规则来决定允许哪些IP。
#
$IPTABLES -A 输出 -p 全部 -s $LO_IP -j 接受
$IPTABLES -A 输出 -p 全部 -s $LAN_IP -j 接受
$IPTABLES -A 输出 -p 全部 -o $INET_IFACE -j 接受
#
# 记录与上面不匹配的奇怪数据包。
#
$IPTABLES -A 输出 -m limit --limit 3/分钟 --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT 数据包已死亡:"
######
# 4.2 nat表
#
#
# 4.2.1 设置策略
#
#
# 4.2.2 创建用户指定链
#
#
# 4.2.3 在用户指定链中创建内容
#
#
# 4.2.4 PREROUTING链
#
#
# 4.2.5 POSTROUTING链
#
如果 [ $PPPOE_PMTU == "是"] ; 然后
$IPTABLES -t nat -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
菲
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE
#
# 4.2.6 输出链
#
######
# 4.3 变形表
#
#
# 4.3.1 设置策略
#
#
# 4.3.2 创建用户指定链
#
#
# 4.3.3 在用户指定链中创建内容
#
#
# 4.3.4 PREROUTING链
#
#
# 4.3.5 INPUT链
#
#
# 4.3.6 FORWARD链
#
#
# 4.3.7 输出链
#
#
# 4.3.8 POSTROUTING链
#
#!/bin/sh
#
# rc.DHCP.firewall - DHCP IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
###########################################################################
#
# 1. Configuration options.
#
#
# 1.1 Internet Configuration.
#
INET_IFACE="eth0"
#
# 1.1.1 DHCP
#
#
# Information pertaining to DHCP over the Internet, if needed.
#
# Set DHCP variable to no if you don't get IP from DHCP. If you get DHCP
# over the Internet set this variable to yes, and set up the proper IP
# address for the DHCP server in the DHCP_SERVER variable.
#
DHCP="no"
DHCP_SERVER="195.22.90.65"
#
# 1.1.2 PPPoE
#
# Configuration options pertaining to PPPoE.
#
# If you have problem with your PPPoE connection, such as large mails not
# getting through while small mail get through properly etc, you may set
# this option to "yes" which may fix the problem. This option will set a
# rule in the PREROUTING chain of the mangle table which will clamp
# (resize) all routed packets to PMTU (Path Maximum Transmit Unit).
#
# Note that it is better to set this up in the PPPoE package itself, since
# the PPPoE configuration option will give less overhead.
#
PPPOE_PMTU="no"
#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#
LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"
#
# 1.3 DMZ Configuration.
#
#
# 1.4 Localhost Configuration.
#
LO_IFACE="lo"
LO_IP="127.0.0.1"
#
# 1.5 IPTables Configuration.
#
IPTABLES="/usr/sbin/iptables"
#
# 1.6 Other Configuration.
#
###########################################################################
#
# 2. Module loading.
#
#
# Needed to initially load modules
#
/sbin/depmod -a
#
# 2.1 Required modules
#
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_tables
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_MASQUERADE
#
# 2.2 Non-Required modules
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
###########################################################################
#
# 3. /proc set up.
#
#
# 3.1 Required proc configuration
#
echo "1" > /proc/sys/net/ipv4/ip_forward
#
# 3.2 Non-Required proc configuration
#
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
###########################################################################
#
# 4. rules set up.
#
######
# 4.1 Filter table
#
#
# 4.1.1 Set policies
#
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
#
# 4.1.2 Create userspecified chains
#
#
# Create chain for bad tcp packets
#
$IPTABLES -N bad_tcp_packets
#
# Create separate chains for ICMP, TCP and UDP to traverse
#
$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# 4.1.3 Create content in userspecified chains
#
#
# bad_tcp_packets chain
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
#
# allowed chain
#
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP
#
# TCP rules
#
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed
#
# UDP ports
#
$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
if [ $DHCP == "yes" ] ; then
$IPTABLES -A udp_packets -p UDP -s $DHCP_SERVER --sport 67 \
--dport 68 -j ACCEPT
fi
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT
#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE \
#--destination-port 135:139 -j DROP
#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#
#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP
#
# ICMP rules
#
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
#
# 4.1.4 INPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
#
# Rules for special networks not part of the Internet
#
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -j ACCEPT
#
# Special rule for DHCP requests from LAN, which are not caught properly
# otherwise.
#
$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT
#
# Rules for incoming packets from the internet.
#
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#
#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP
#
# Log weird packets that don't match the above.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "
#
# 4.1.5 FORWARD chain
#
#
# Bad TCP packets we don't want
#
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
#
# Accept the packets we actually want to forward
#
$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "
#
# 4.1.6 OUTPUT chain
#
#
# Bad TCP packets we don't want.
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
#
# Special OUTPUT rules to decide which IP's to allow.
#
$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT
#
# Log weird packets that don't match the above.
#
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
######
# 4.2 nat table
#
#
# 4.2.1 Set policies
#
#
# 4.2.2 Create user specified chains
#
#
# 4.2.3 Create content in user specified chains
#
#
# 4.2.4 PREROUTING chain
#
#
# 4.2.5 POSTROUTING chain
#
if [ $PPPOE_PMTU == "yes" ] ; then
$IPTABLES -t nat -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
fi
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE
#
# 4.2.6 OUTPUT chain
#
######
# 4.3 mangle table
#
#
# 4.3.1 Set policies
#
#
# 4.3.2 Create user specified chains
#
#
# 4.3.3 Create content in user specified chains
#
#
# 4.3.4 PREROUTING chain
#
#
# 4.3.5 INPUT chain
#
#
# 4.3.6 FORWARD chain
#
#
# 4.3.7 OUTPUT chain
#
#
# 4.3.8 POSTROUTING chain
#
#!/bin/sh
#
# rc.flush-iptables - 将 iptables 重置为默认值。
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
# 配置
#
IPTABLES =“/ usr / sbin / iptables”
#
# 重置过滤表中的默认策略。
#
$IPTABLES -P 输入接受
$IPTABLES -P 转发接受
$IPTABLES -P 输出接受
#
# 重置 nat 表中的默认策略。
#
$IPTABLES -t nat -P PREROUTING接受
$IPTABLES -t nat -P 后路由接受
$IPTABLES -t nat -P 输出接受
#
# 重置 mangle 表中的默认策略。
#
$IPTABLES -t mangle -P PREROUTING接受
$IPTABLES -t mangle -P POSTROUTING 接受
$IPTABLES -t mangle -P 输入接受
$IPTABLES -t mangle -P 输出接受
$IPTABLES -t mangle -P 转发接受
#
# 刷新过滤器和 nat 表中的所有规则。
#
$IP表-F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
#
# 删除过滤器和 nat 表中所有非默认的链。
#
$IP表-X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
#!/bin/sh
#
# rc.flush-iptables - Resets iptables to default values.
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Configurations
#
IPTABLES="/usr/sbin/iptables"
#
# reset the default policies in the filter table.
#
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
#
# reset the default policies in the nat table.
#
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t nat -P OUTPUT ACCEPT
#
# reset the default policies in the mangle table.
#
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P POSTROUTING ACCEPT
$IPTABLES -t mangle -P INPUT ACCEPT
$IPTABLES -t mangle -P OUTPUT ACCEPT
$IPTABLES -t mangle -P FORWARD ACCEPT
#
# flush all the rules in the filter and nat tables.
#
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
#
# erase all chains that's not default in filter and nat table.
#
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
#!/bin/bash
#
# rc.test-iptables - iptables 链和表的测试脚本。
#
# 版权所有 (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# 该程序是免费软件;您可以重新分发它和/或修改
# 它遵循 GNU 通用公共许可证的条款,由
# 自由软件基金会;许可证的版本 2。
#
# 这个程序发布是为了希望它有用,
# 但没有任何保证;甚至没有默示保证
# 适销性或特定用途的适用性。请参阅
# GNU 通用公共许可证了解更多详细信息。
#
# 您应该已经收到一份 GNU 通用公共许可证的副本
# 与此程序一起或从您下载它的网站
# 从; 如果没有,请写信给 Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 美国
#
#
# 过滤表,所有链
#
iptables -t 过滤器 -A 输入 -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix="过滤输入:"
iptables -t 过滤器 -A 输入 -p icmp --icmp 类型回显回复 \
-j LOG --log-prefix="过滤输入:"
iptables -t 过滤器 -A 输出 -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix="过滤输出:"
iptables -t 过滤器 -A 输出 -p icmp --icmp 类型回显回复 \
-j LOG --log-prefix="过滤输出:"
iptables -t 过滤器 -A FORWARD -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix="过滤转发:"
iptables -t 过滤器 -A FORWARD -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="过滤转发:"
#
# NAT 表,除 OUTPUT 之外的所有链都不起作用。
#
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix =“nat PREROUTING:”
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix =“nat PREROUTING:”
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix =“nat POSTROUTING:”
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix =“nat POSTROUTING:”
iptables -t nat -A 输出 -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix =“nat 输出:”
iptables -t nat -A 输出 -p icmp --icmp 类型回显回复 \
-j LOG --log-prefix =“nat 输出:”
#
# Mangle 表,所有链
#
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle 转发:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle 转发:"
iptables -t mangle -I 输入 1 -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix="mangle 输入:"
iptables -t mangle -I 输入 1 -p icmp --icmp 类型回显回复 \
-j LOG --log-prefix="mangle 输入:"
iptables -t mangle -A 输出 -p icmp --icmp 类型回显请求 \
-j LOG --log-prefix="mangle 输出:"
iptables -t mangle -A 输出 -p icmp --icmp 类型回显回复 \
-j LOG --log-prefix="mangle 输出:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle POSTROUTING:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle POSTROUTING:"
#!/bin/bash
#
# rc.test-iptables - test script for iptables chains and tables.
#
# Copyright (C) 2001 Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Filter table, all chains
#
iptables -t filter -A INPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A INPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter FORWARD:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter FORWARD:"
#
# NAT table, all chains except OUTPUT which don't work.
#
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat OUTPUT:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat OUTPUT:"
#
# Mangle table, all chains
#
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle POSTROUTING:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle POSTROUTING:"